{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 16.1 Splitting an object into groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Program Files\\Anaconda3\\lib\\importlib\\_bootstrap.py:222: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88\n",
      "  return f(*args, **kwds)\n"
     ]
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>foo</td>\n",
       "      <td>one</td>\n",
       "      <td>-1.124461</td>\n",
       "      <td>0.677408</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>bar</td>\n",
       "      <td>one</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.756952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>foo</td>\n",
       "      <td>two</td>\n",
       "      <td>1.085252</td>\n",
       "      <td>-0.811569</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>bar</td>\n",
       "      <td>three</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.788776</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>foo</td>\n",
       "      <td>two</td>\n",
       "      <td>0.486710</td>\n",
       "      <td>-0.106797</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>bar</td>\n",
       "      <td>two</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>-0.978453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>foo</td>\n",
       "      <td>one</td>\n",
       "      <td>0.391403</td>\n",
       "      <td>-0.301258</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>foo</td>\n",
       "      <td>three</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-0.545103</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     A      B         C         D\n",
       "0  foo    one -1.124461  0.677408\n",
       "1  bar    one -0.830092 -0.756952\n",
       "2  foo    two  1.085252 -0.811569\n",
       "3  bar  three -0.865654 -0.788776\n",
       "4  foo    two  0.486710 -0.106797\n",
       "5  bar    two  0.099086 -0.978453\n",
       "6  foo    one  0.391403 -0.301258\n",
       "7  foo  three -1.171082 -0.545103"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar','foo', 'bar', 'foo', 'foo'],\n",
    "                   'B' : ['one', 'one', 'two', 'three','two', 'two', 'one', 'three'],\n",
    "                   'C' : np.random.randn(8),\n",
    "                   'D' : np.random.randn(8)})\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = df.groupby('A')\n",
    "grouped = df.groupby(['A', 'B'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    " def get_letter_type(letter):\n",
    "        if letter.lower() in 'aeiou':\n",
    "            return 'vowel'\n",
    "        else:\n",
    "            return 'consonant'\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    " grouped = df.groupby(get_letter_type, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "显然，get_letter_type函数的返回值就是group name，显然这个函数定义了a mapping of lable to group name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1     1\n",
       "2     2\n",
       "3     3\n",
       "1    10\n",
       "2    20\n",
       "3    30\n",
       "dtype: int64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lst = [1, 2, 3, 1, 2, 3]\n",
    "s = pd.Series([1, 2, 3, 10, 20, 30], lst)\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = s.groupby(level=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意：看完了multiindex，应该需要对level敏感了，显然，当groupby函数的参数level被指定的情况下，也就表明要使用index来进行分组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1    1\n",
       "2    2\n",
       "3    3\n",
       "dtype: int64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.first()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1    10\n",
       "2    20\n",
       "3    30\n",
       "dtype: int64"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.last()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1    11\n",
       "2    22\n",
       "3    33\n",
       "dtype: int64"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.1.1 GroupBy sorting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>B</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>B</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>A</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>A</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   X  Y\n",
       "0  B  1\n",
       "1  B  2\n",
       "2  A  3\n",
       "3  A  4"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df2 = pd.DataFrame({'X' : ['B', 'B', 'A', 'A'], 'Y' : [1, 2, 3, 4]})\n",
    "df2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Y</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>X</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Y\n",
       "X   \n",
       "A  7\n",
       "B  3"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df2.groupby(['X']).sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Y</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>X</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Y\n",
       "X   \n",
       "B  3\n",
       "A  7"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df2.groupby(['X'], sort=False).sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>A</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>B</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>A</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>B</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   X  Y\n",
       "0  A  1\n",
       "1  B  4\n",
       "2  A  3\n",
       "3  B  2"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df3 = pd.DataFrame({'X' : ['A', 'B', 'A', 'B'], 'Y' : [1, 4, 3, 2]})\n",
    "df3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>A</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>A</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   X  Y\n",
       "0  A  1\n",
       "2  A  3"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df3.groupby(['X']).get_group('A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>B</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>B</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   X  Y\n",
       "1  B  4\n",
       "3  B  2"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df3.groupby(['X']).get_group('B')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.1.2 GroupBy object attributes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>foo</td>\n",
       "      <td>one</td>\n",
       "      <td>2.699105</td>\n",
       "      <td>0.301294</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>bar</td>\n",
       "      <td>one</td>\n",
       "      <td>-1.417945</td>\n",
       "      <td>-2.317604</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>foo</td>\n",
       "      <td>two</td>\n",
       "      <td>-0.227279</td>\n",
       "      <td>1.471652</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>bar</td>\n",
       "      <td>three</td>\n",
       "      <td>0.476644</td>\n",
       "      <td>-1.325698</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>foo</td>\n",
       "      <td>two</td>\n",
       "      <td>0.705054</td>\n",
       "      <td>-1.371071</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>bar</td>\n",
       "      <td>two</td>\n",
       "      <td>-0.476645</td>\n",
       "      <td>1.102865</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>foo</td>\n",
       "      <td>one</td>\n",
       "      <td>0.505329</td>\n",
       "      <td>-1.346775</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>foo</td>\n",
       "      <td>three</td>\n",
       "      <td>0.333910</td>\n",
       "      <td>0.422853</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     A      B         C         D\n",
       "0  foo    one  2.699105  0.301294\n",
       "1  bar    one -1.417945 -2.317604\n",
       "2  foo    two -0.227279  1.471652\n",
       "3  bar  three  0.476644 -1.325698\n",
       "4  foo    two  0.705054 -1.371071\n",
       "5  bar    two -0.476645  1.102865\n",
       "6  foo    one  0.505329 -1.346775\n",
       "7  foo  three  0.333910  0.422853"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'bar': Int64Index([1, 3, 5], dtype='int64'),\n",
       " 'foo': Int64Index([0, 2, 4, 6, 7], dtype='int64')}"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('A').groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'consonant': Index(['B', 'C', 'D'], dtype='object'),\n",
       " 'vowel': Index(['A'], dtype='object')}"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(get_letter_type, axis=1).groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{('bar', 'one'): Int64Index([1], dtype='int64'),\n",
       " ('bar', 'three'): Int64Index([3], dtype='int64'),\n",
       " ('bar', 'two'): Int64Index([5], dtype='int64'),\n",
       " ('foo', 'one'): Int64Index([0, 6], dtype='int64'),\n",
       " ('foo', 'three'): Int64Index([7], dtype='int64'),\n",
       " ('foo', 'two'): Int64Index([2, 4], dtype='int64')}"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped = df.groupby(['A', 'B'])\n",
    "grouped.groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(grouped)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.1.3 GroupBy with MultiIndex"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "first  second\n",
       "bar    one      -0.737608\n",
       "       two       1.061706\n",
       "baz    one      -1.026070\n",
       "       two       1.164503\n",
       "foo    one       1.469209\n",
       "       two       0.288029\n",
       "qux    one       0.904783\n",
       "       two       0.050478\n",
       "dtype: float64"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],\n",
    "           ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]\n",
    "index = pd.MultiIndex.from_arrays(arrays, names=['first', 'second'])\n",
    "s = pd.Series(np.random.randn(8), index=index)\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "first\n",
       "bar    0.324098\n",
       "baz    0.138433\n",
       "foo    1.757238\n",
       "qux    0.955260\n",
       "dtype: float64"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped = s.groupby(level=0)\n",
    "grouped.sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "second\n",
       "one    0.610312\n",
       "two    2.564717\n",
       "dtype: float64"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.groupby(level='second').sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "second\n",
       "one    0.610312\n",
       "two    2.564717\n",
       "dtype: float64"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.sum(level='second')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.1.4 Grouping DataFrame with Index Levels and Columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>first</th>\n",
       "      <th>second</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">bar</th>\n",
       "      <th>one</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">baz</th>\n",
       "      <th>one</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">foo</th>\n",
       "      <th>one</th>\n",
       "      <td>2</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">qux</th>\n",
       "      <th>one</th>\n",
       "      <td>3</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>3</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              A  B\n",
       "first second      \n",
       "bar   one     1  0\n",
       "      two     1  1\n",
       "baz   one     1  2\n",
       "      two     1  3\n",
       "foo   one     2  4\n",
       "      two     2  5\n",
       "qux   one     3  6\n",
       "      two     3  7"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]\n",
    "index = pd.MultiIndex.from_arrays(arrays, names=['first', 'second'])\n",
    "df = pd.DataFrame({'A': [1, 1, 1, 1, 2, 2, 3, 3],'B': np.arange(8)},index=index)\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>second</th>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">one</th>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">two</th>\n",
       "      <th>1</th>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          B\n",
       "second A   \n",
       "one    1  2\n",
       "       2  4\n",
       "       3  6\n",
       "two    1  4\n",
       "       2  5\n",
       "       3  7"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby([pd.Grouper(level=1), 'A']).sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>second</th>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">one</th>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">two</th>\n",
       "      <th>1</th>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          B\n",
       "second A   \n",
       "one    1  2\n",
       "       2  4\n",
       "       3  6\n",
       "two    1  4\n",
       "       2  5\n",
       "       3  7"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby([pd.Grouper(level='second'), 'A']).sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>second</th>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">one</th>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">two</th>\n",
       "      <th>1</th>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          B\n",
       "second A   \n",
       "one    1  2\n",
       "       2  4\n",
       "       3  6\n",
       "two    1  4\n",
       "       2  5\n",
       "       3  7"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(['second', 'A']).sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.1.5 DataFrame column selection in GroupBy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = df.groupby(['A'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'Column not found: C'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-43-0c08a12bda5b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mgrouped_C\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgrouped\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'C'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32mD:\\Program Files\\Anaconda3\\lib\\site-packages\\pandas\\core\\base.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m    265\u001b[0m         \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m    266\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mkey\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mobj\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 267\u001b[0;31m                 \u001b[1;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Column not found: {key}\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    268\u001b[0m             \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_gotitem\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mndim\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m    269\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'Column not found: C'"
     ]
    }
   ],
   "source": [
    "grouped_C = grouped['C']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'Column not found: D'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-44-de261d4a7dc6>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mgrouped_D\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgrouped\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'D'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32mD:\\Program Files\\Anaconda3\\lib\\site-packages\\pandas\\core\\base.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m    265\u001b[0m         \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m    266\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mkey\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mobj\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 267\u001b[0;31m                 \u001b[1;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Column not found: {key}\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    268\u001b[0m             \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_gotitem\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mndim\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m    269\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'Column not found: D'"
     ]
    }
   ],
   "source": [
    "grouped_D = grouped['D']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'C'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32mD:\\Program Files\\Anaconda3\\lib\\site-packages\\pandas\\core\\indexes\\base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m   3077\u001b[0m             \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3078\u001b[0;31m                 \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   3079\u001b[0m             \u001b[1;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[0;32mpandas\\_libs\\index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;32mpandas\\_libs\\index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;32mpandas\\_libs\\hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;32mpandas\\_libs\\hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'C'",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-45-3c09182074cc>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdf\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'C'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgroupby\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'A'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32mD:\\Program Files\\Anaconda3\\lib\\site-packages\\pandas\\core\\frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m   2686\u001b[0m             \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   2687\u001b[0m         \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2688\u001b[0;31m             \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_getitem_column\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2689\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   2690\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0m_getitem_column\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[0;32mD:\\Program Files\\Anaconda3\\lib\\site-packages\\pandas\\core\\frame.py\u001b[0m in \u001b[0;36m_getitem_column\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m   2693\u001b[0m         \u001b[1;31m# get column\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   2694\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mis_unique\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2695\u001b[0;31m             \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_get_item_cache\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2696\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   2697\u001b[0m         \u001b[1;31m# duplicate columns & possible reduce dimensionality\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[0;32mD:\\Program Files\\Anaconda3\\lib\\site-packages\\pandas\\core\\generic.py\u001b[0m in \u001b[0;36m_get_item_cache\u001b[0;34m(self, item)\u001b[0m\n\u001b[1;32m   2487\u001b[0m         \u001b[0mres\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcache\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   2488\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mres\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2489\u001b[0;31m             \u001b[0mvalues\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_data\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2490\u001b[0m             \u001b[0mres\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_box_item_values\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   2491\u001b[0m             \u001b[0mcache\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mitem\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mres\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[0;32mD:\\Program Files\\Anaconda3\\lib\\site-packages\\pandas\\core\\internals.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, item, fastpath)\u001b[0m\n\u001b[1;32m   4113\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   4114\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0misna\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4115\u001b[0;31m                 \u001b[0mloc\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   4116\u001b[0m             \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   4117\u001b[0m                 \u001b[0mindexer\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0misna\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[0;32mD:\\Program Files\\Anaconda3\\lib\\site-packages\\pandas\\core\\indexes\\base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m   3078\u001b[0m                 \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   3079\u001b[0m             \u001b[1;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3080\u001b[0;31m                 \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_maybe_cast_indexer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   3081\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m   3082\u001b[0m         \u001b[0mindexer\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_indexer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtolerance\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mtolerance\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[0;32mpandas\\_libs\\index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;32mpandas\\_libs\\index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;32mpandas\\_libs\\hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;32mpandas\\_libs\\hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'C'"
     ]
    }
   ],
   "source": [
    "df['C'].groupby(df['A'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 16.2 Iterating through groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = df.groupby('A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "              A  B\n",
      "first second      \n",
      "bar   one     1  0\n",
      "      two     1  1\n",
      "baz   one     1  2\n",
      "      two     1  3\n",
      "2\n",
      "              A  B\n",
      "first second      \n",
      "foo   one     2  4\n",
      "      two     2  5\n",
      "3\n",
      "              A  B\n",
      "first second      \n",
      "qux   one     3  6\n",
      "      two     3  7\n"
     ]
    }
   ],
   "source": [
    " for name, group in grouped:\n",
    "        print(name)\n",
    "        print(group)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 16.3 Selecting a group"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>first</th>\n",
       "      <th>second</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">bar</th>\n",
       "      <th>one</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">baz</th>\n",
       "      <th>one</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              A  B\n",
       "first second      \n",
       "bar   one     1  0\n",
       "      two     1  1\n",
       "baz   one     1  2\n",
       "      two     1  3"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.get_group(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 0)\n",
      "              A  B\n",
      "first second      \n",
      "bar   one     1  0\n",
      "(1, 1)\n",
      "              A  B\n",
      "first second      \n",
      "bar   two     1  1\n",
      "(1, 2)\n",
      "              A  B\n",
      "first second      \n",
      "baz   one     1  2\n",
      "(1, 3)\n",
      "              A  B\n",
      "first second      \n",
      "baz   two     1  3\n",
      "(2, 4)\n",
      "              A  B\n",
      "first second      \n",
      "foo   one     2  4\n",
      "(2, 5)\n",
      "              A  B\n",
      "first second      \n",
      "foo   two     2  5\n",
      "(3, 6)\n",
      "              A  B\n",
      "first second      \n",
      "qux   one     3  6\n",
      "(3, 7)\n",
      "              A  B\n",
      "first second      \n",
      "qux   two     3  7\n"
     ]
    }
   ],
   "source": [
    "\n",
    "for name, group in df.groupby(['A', 'B']):\n",
    "    print(name)\n",
    "    print(group)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>first</th>\n",
       "      <th>second</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <th>one</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              A  B\n",
       "first second      \n",
       "bar   one     1  0"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(['A', 'B']).get_group((1, 0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 16.4 Aggregation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = df.groupby('A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>-1.596660</td>\n",
       "      <td>-2.524181</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>-0.332177</td>\n",
       "      <td>-1.087319</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            C         D\n",
       "A                      \n",
       "bar -1.596660 -2.524181\n",
       "foo -0.332177 -1.087319"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.aggregate(np.sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = df.groupby(['A', 'B'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">bar</th>\n",
       "      <th>one</th>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.756952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>three</th>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.788776</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>0.099086</td>\n",
       "      <td>-0.978453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">foo</th>\n",
       "      <th>one</th>\n",
       "      <td>-0.733058</td>\n",
       "      <td>0.376150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>three</th>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-0.545103</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>1.571963</td>\n",
       "      <td>-0.918366</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  C         D\n",
       "A   B                        \n",
       "bar one   -0.830092 -0.756952\n",
       "    three -0.865654 -0.788776\n",
       "    two    0.099086 -0.978453\n",
       "foo one   -0.733058  0.376150\n",
       "    three -1.171082 -0.545103\n",
       "    two    1.571963 -0.918366"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.aggregate(np.sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>bar</td>\n",
       "      <td>one</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.756952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>bar</td>\n",
       "      <td>three</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.788776</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>bar</td>\n",
       "      <td>two</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>-0.978453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>foo</td>\n",
       "      <td>one</td>\n",
       "      <td>-0.733058</td>\n",
       "      <td>0.376150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>foo</td>\n",
       "      <td>three</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-0.545103</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>foo</td>\n",
       "      <td>two</td>\n",
       "      <td>1.571963</td>\n",
       "      <td>-0.918366</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     A      B         C         D\n",
       "0  bar    one -0.830092 -0.756952\n",
       "1  bar  three -0.865654 -0.788776\n",
       "2  bar    two  0.099086 -0.978453\n",
       "3  foo    one -0.733058  0.376150\n",
       "4  foo  three -1.171082 -0.545103\n",
       "5  foo    two  1.571963 -0.918366"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped = df.groupby(['A', 'B'], as_index=False)\n",
    "grouped.aggregate(np.sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>bar</td>\n",
       "      <td>-1.596660</td>\n",
       "      <td>-2.524181</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>foo</td>\n",
       "      <td>-0.332177</td>\n",
       "      <td>-1.087319</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     A         C         D\n",
       "0  bar -1.596660 -2.524181\n",
       "1  foo -0.332177 -1.087319"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('A', as_index=False).sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>bar</td>\n",
       "      <td>one</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.756952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>bar</td>\n",
       "      <td>three</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.788776</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>bar</td>\n",
       "      <td>two</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>-0.978453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>foo</td>\n",
       "      <td>one</td>\n",
       "      <td>-0.733058</td>\n",
       "      <td>0.376150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>foo</td>\n",
       "      <td>three</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-0.545103</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>foo</td>\n",
       "      <td>two</td>\n",
       "      <td>1.571963</td>\n",
       "      <td>-0.918366</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     A      B         C         D\n",
       "0  bar    one -0.830092 -0.756952\n",
       "1  bar  three -0.865654 -0.788776\n",
       "2  bar    two  0.099086 -0.978453\n",
       "3  foo    one -0.733058  0.376150\n",
       "4  foo  three -1.171082 -0.545103\n",
       "5  foo    two  1.571963 -0.918366"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(['A', 'B']).sum().reset_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "A    B    \n",
       "bar  one      1\n",
       "     three    1\n",
       "     two      1\n",
       "foo  one      2\n",
       "     three    1\n",
       "     two      2\n",
       "dtype: int64"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"8\" halign=\"left\">C</th>\n",
       "      <th colspan=\"8\" halign=\"left\">D</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "      <th>min</th>\n",
       "      <th>25%</th>\n",
       "      <th>50%</th>\n",
       "      <th>75%</th>\n",
       "      <th>max</th>\n",
       "      <th>count</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "      <th>min</th>\n",
       "      <th>25%</th>\n",
       "      <th>50%</th>\n",
       "      <th>75%</th>\n",
       "      <th>max</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>NaN</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.830092</td>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.756952</td>\n",
       "      <td>NaN</td>\n",
       "      <td>-0.756952</td>\n",
       "      <td>-0.756952</td>\n",
       "      <td>-0.756952</td>\n",
       "      <td>-0.756952</td>\n",
       "      <td>-0.756952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>NaN</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.865654</td>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.788776</td>\n",
       "      <td>NaN</td>\n",
       "      <td>-0.788776</td>\n",
       "      <td>-0.788776</td>\n",
       "      <td>-0.788776</td>\n",
       "      <td>-0.788776</td>\n",
       "      <td>-0.788776</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>0.099086</td>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.978453</td>\n",
       "      <td>NaN</td>\n",
       "      <td>-0.978453</td>\n",
       "      <td>-0.978453</td>\n",
       "      <td>-0.978453</td>\n",
       "      <td>-0.978453</td>\n",
       "      <td>-0.978453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2.0</td>\n",
       "      <td>-0.366529</td>\n",
       "      <td>1.071878</td>\n",
       "      <td>-1.124461</td>\n",
       "      <td>-0.745495</td>\n",
       "      <td>-0.366529</td>\n",
       "      <td>0.012437</td>\n",
       "      <td>0.391403</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.188075</td>\n",
       "      <td>0.692022</td>\n",
       "      <td>-0.301258</td>\n",
       "      <td>-0.056592</td>\n",
       "      <td>0.188075</td>\n",
       "      <td>0.432742</td>\n",
       "      <td>0.677408</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>NaN</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-1.171082</td>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.545103</td>\n",
       "      <td>NaN</td>\n",
       "      <td>-0.545103</td>\n",
       "      <td>-0.545103</td>\n",
       "      <td>-0.545103</td>\n",
       "      <td>-0.545103</td>\n",
       "      <td>-0.545103</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>2.0</td>\n",
       "      <td>0.785981</td>\n",
       "      <td>0.423233</td>\n",
       "      <td>0.486710</td>\n",
       "      <td>0.636346</td>\n",
       "      <td>0.785981</td>\n",
       "      <td>0.935617</td>\n",
       "      <td>1.085252</td>\n",
       "      <td>2.0</td>\n",
       "      <td>-0.459183</td>\n",
       "      <td>0.498349</td>\n",
       "      <td>-0.811569</td>\n",
       "      <td>-0.635376</td>\n",
       "      <td>-0.459183</td>\n",
       "      <td>-0.282990</td>\n",
       "      <td>-0.106797</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      C                                                                        \\\n",
       "  count      mean       std       min       25%       50%       75%       max   \n",
       "0   1.0 -0.830092       NaN -0.830092 -0.830092 -0.830092 -0.830092 -0.830092   \n",
       "1   1.0 -0.865654       NaN -0.865654 -0.865654 -0.865654 -0.865654 -0.865654   \n",
       "2   1.0  0.099086       NaN  0.099086  0.099086  0.099086  0.099086  0.099086   \n",
       "3   2.0 -0.366529  1.071878 -1.124461 -0.745495 -0.366529  0.012437  0.391403   \n",
       "4   1.0 -1.171082       NaN -1.171082 -1.171082 -1.171082 -1.171082 -1.171082   \n",
       "5   2.0  0.785981  0.423233  0.486710  0.636346  0.785981  0.935617  1.085252   \n",
       "\n",
       "      D                                                                        \n",
       "  count      mean       std       min       25%       50%       75%       max  \n",
       "0   1.0 -0.756952       NaN -0.756952 -0.756952 -0.756952 -0.756952 -0.756952  \n",
       "1   1.0 -0.788776       NaN -0.788776 -0.788776 -0.788776 -0.788776 -0.788776  \n",
       "2   1.0 -0.978453       NaN -0.978453 -0.978453 -0.978453 -0.978453 -0.978453  \n",
       "3   2.0  0.188075  0.692022 -0.301258 -0.056592  0.188075  0.432742  0.677408  \n",
       "4   1.0 -0.545103       NaN -0.545103 -0.545103 -0.545103 -0.545103 -0.545103  \n",
       "5   2.0 -0.459183  0.498349 -0.811569 -0.635376 -0.459183 -0.282990 -0.106797  "
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.4.1 Applying multiple functions at once"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sum</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>-1.596660</td>\n",
       "      <td>-0.532220</td>\n",
       "      <td>0.547016</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>-0.332177</td>\n",
       "      <td>-0.066435</td>\n",
       "      <td>1.022452</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          sum      mean       std\n",
       "A                                \n",
       "bar -1.596660 -0.532220  0.547016\n",
       "foo -0.332177 -0.066435  1.022452"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped = df.groupby('A')\n",
    "grouped['C'].agg([np.sum, np.mean, np.std])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"3\" halign=\"left\">C</th>\n",
       "      <th colspan=\"3\" halign=\"left\">D</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>sum</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "      <th>sum</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>-1.596660</td>\n",
       "      <td>-0.532220</td>\n",
       "      <td>0.547016</td>\n",
       "      <td>-2.524181</td>\n",
       "      <td>-0.841394</td>\n",
       "      <td>0.119759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>-0.332177</td>\n",
       "      <td>-0.066435</td>\n",
       "      <td>1.022452</td>\n",
       "      <td>-1.087319</td>\n",
       "      <td>-0.217464</td>\n",
       "      <td>0.565768</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            C                             D                    \n",
       "          sum      mean       std       sum      mean       std\n",
       "A                                                              \n",
       "bar -1.596660 -0.532220  0.547016 -2.524181 -0.841394  0.119759\n",
       "foo -0.332177 -0.066435  1.022452 -1.087319 -0.217464  0.565768"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.agg([np.sum, np.mean, np.std])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>foo</th>\n",
       "      <th>bar</th>\n",
       "      <th>baz</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>-1.596660</td>\n",
       "      <td>-0.532220</td>\n",
       "      <td>0.547016</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>-0.332177</td>\n",
       "      <td>-0.066435</td>\n",
       "      <td>1.022452</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          foo       bar       baz\n",
       "A                                \n",
       "bar -1.596660 -0.532220  0.547016\n",
       "foo -0.332177 -0.066435  1.022452"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(grouped['C'].agg([np.sum, np.mean, np.std]).rename(columns={'sum': 'foo','mean': 'bar','std': 'baz'}))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"3\" halign=\"left\">C</th>\n",
       "      <th colspan=\"3\" halign=\"left\">D</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>foo</th>\n",
       "      <th>bar</th>\n",
       "      <th>baz</th>\n",
       "      <th>foo</th>\n",
       "      <th>bar</th>\n",
       "      <th>baz</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>-1.596660</td>\n",
       "      <td>-0.532220</td>\n",
       "      <td>0.547016</td>\n",
       "      <td>-2.524181</td>\n",
       "      <td>-0.841394</td>\n",
       "      <td>0.119759</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>-0.332177</td>\n",
       "      <td>-0.066435</td>\n",
       "      <td>1.022452</td>\n",
       "      <td>-1.087319</td>\n",
       "      <td>-0.217464</td>\n",
       "      <td>0.565768</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            C                             D                    \n",
       "          foo       bar       baz       foo       bar       baz\n",
       "A                                                              \n",
       "bar -1.596660 -0.532220  0.547016 -2.524181 -0.841394  0.119759\n",
       "foo -0.332177 -0.066435  1.022452 -1.087319 -0.217464  0.565768"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(grouped.agg([np.sum, np.mean, np.std]).rename(columns={'sum': 'foo','mean': 'bar','std': 'baz'}))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.4.2 Applying different functions to DataFrame columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>D</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>0.119759</td>\n",
       "      <td>-1.596660</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>0.565768</td>\n",
       "      <td>-0.332177</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            D         C\n",
       "A                      \n",
       "bar  0.119759 -1.596660\n",
       "foo  0.565768 -0.332177"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.agg({'C' : np.sum,'D' : lambda x: np.std(x, ddof=1)})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>D</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>0.119759</td>\n",
       "      <td>-1.596660</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>0.565768</td>\n",
       "      <td>-0.332177</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            D         C\n",
       "A                      \n",
       "bar  0.119759 -1.596660\n",
       "foo  0.565768 -0.332177"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.agg({'C' : 'sum', 'D' : 'std'})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>D</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>0.119759</td>\n",
       "      <td>-0.532220</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>0.565768</td>\n",
       "      <td>-0.066435</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            D         C\n",
       "A                      \n",
       "bar  0.119759 -0.532220\n",
       "foo  0.565768 -0.066435"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.agg({'D': 'std', 'C': 'mean'})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'OrderedDict' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-78-9e672eb45ac6>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mgrouped\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0magg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mOrderedDict\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'D'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'std'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;34m'C'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'mean'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'OrderedDict' is not defined"
     ]
    }
   ],
   "source": [
    "grouped.agg(OrderedDict([('D', 'std'), ('C', 'mean')]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.4.3 Cython-optimized aggregation functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>bar</th>\n",
       "      <td>-1.596660</td>\n",
       "      <td>-2.524181</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>foo</th>\n",
       "      <td>-0.332177</td>\n",
       "      <td>-1.087319</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            C         D\n",
       "A                      \n",
       "bar -1.596660 -2.524181\n",
       "foo -0.332177 -1.087319"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('A').sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">bar</th>\n",
       "      <th>one</th>\n",
       "      <td>-0.830092</td>\n",
       "      <td>-0.756952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>three</th>\n",
       "      <td>-0.865654</td>\n",
       "      <td>-0.788776</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>0.099086</td>\n",
       "      <td>-0.978453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">foo</th>\n",
       "      <th>one</th>\n",
       "      <td>-0.366529</td>\n",
       "      <td>0.188075</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>three</th>\n",
       "      <td>-1.171082</td>\n",
       "      <td>-0.545103</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>0.785981</td>\n",
       "      <td>-0.459183</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  C         D\n",
       "A   B                        \n",
       "bar one   -0.830092 -0.756952\n",
       "    three -0.865654 -0.788776\n",
       "    two    0.099086 -0.978453\n",
       "foo one   -0.366529  0.188075\n",
       "    three -1.171082 -0.545103\n",
       "    two    0.785981 -0.459183"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(['A', 'B']).mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 16.5 Transformation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1999-10-01    3.895040\n",
       "1999-10-02   -1.794884\n",
       "1999-10-03   -0.549336\n",
       "1999-10-04    1.175662\n",
       "1999-10-05    7.012307\n",
       "1999-10-06   -1.570899\n",
       "1999-10-07    0.449620\n",
       "1999-10-08    3.875036\n",
       "1999-10-09    0.126549\n",
       "1999-10-10    4.224443\n",
       "1999-10-11   -0.074740\n",
       "1999-10-12    2.181963\n",
       "1999-10-13    2.648256\n",
       "1999-10-14   -0.455911\n",
       "1999-10-15    2.462448\n",
       "1999-10-16   -0.285014\n",
       "1999-10-17   -0.914814\n",
       "1999-10-18    0.366802\n",
       "1999-10-19    0.484768\n",
       "1999-10-20    0.776665\n",
       "1999-10-21   -5.350077\n",
       "1999-10-22    0.180112\n",
       "1999-10-23    0.292692\n",
       "1999-10-24   -3.719334\n",
       "1999-10-25   -0.726607\n",
       "1999-10-26    2.423192\n",
       "1999-10-27    0.865185\n",
       "1999-10-28    1.622921\n",
       "1999-10-29   -2.299035\n",
       "1999-10-30   -0.606634\n",
       "                ...   \n",
       "2002-09-05    0.341872\n",
       "2002-09-06   -1.607443\n",
       "2002-09-07    0.455075\n",
       "2002-09-08    1.602278\n",
       "2002-09-09   -0.216314\n",
       "2002-09-10   -0.414417\n",
       "2002-09-11    0.294726\n",
       "2002-09-12    0.199825\n",
       "2002-09-13   -1.309530\n",
       "2002-09-14    1.831611\n",
       "2002-09-15    1.508550\n",
       "2002-09-16   -0.716191\n",
       "2002-09-17   -4.069087\n",
       "2002-09-18    2.400581\n",
       "2002-09-19    1.595236\n",
       "2002-09-20   -1.897323\n",
       "2002-09-21    1.440077\n",
       "2002-09-22   -3.853513\n",
       "2002-09-23    1.316474\n",
       "2002-09-24   -4.049592\n",
       "2002-09-25   -0.768826\n",
       "2002-09-26    2.210771\n",
       "2002-09-27   -1.205534\n",
       "2002-09-28   -1.011766\n",
       "2002-09-29    0.432340\n",
       "2002-09-30    0.107469\n",
       "2002-10-01    2.510181\n",
       "2002-10-02   -1.281254\n",
       "2002-10-03    0.034451\n",
       "2002-10-04   -3.144342\n",
       "Freq: D, Length: 1100, dtype: float64"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "index = pd.date_range('10/1/1999', periods=1100)\n",
    "ts = pd.Series(np.random.normal(0.5, 2, 1100), index)\n",
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-08    0.691459\n",
       "2000-01-09    0.663604\n",
       "2000-01-10    0.677626\n",
       "2000-01-11    0.691533\n",
       "2000-01-12    0.679053\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts = ts.rolling(window=100,min_periods=100).mean().dropna()\n",
    "ts.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2002-09-30    0.312472\n",
       "2002-10-01    0.300708\n",
       "2002-10-02    0.283550\n",
       "2002-10-03    0.267483\n",
       "2002-10-04    0.281221\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.tail()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "key = lambda x: x.year\n",
    "zscore = lambda x: (x - x.mean()) / x.std()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-08    1.978952\n",
       "2000-01-09    1.805767\n",
       "2000-01-10    1.892947\n",
       "2000-01-11    1.979412\n",
       "2000-01-12    1.901820\n",
       "2000-01-13    1.196683\n",
       "2000-01-14    1.463856\n",
       "2000-01-15    1.510692\n",
       "2000-01-16    1.382519\n",
       "2000-01-17    1.167964\n",
       "2000-01-18    1.069720\n",
       "2000-01-19    0.909008\n",
       "2000-01-20    0.908138\n",
       "2000-01-21    0.788057\n",
       "2000-01-22    0.957387\n",
       "2000-01-23    0.925121\n",
       "2000-01-24    0.851451\n",
       "2000-01-25    0.688959\n",
       "2000-01-26    0.937283\n",
       "2000-01-27    0.789538\n",
       "2000-01-28    0.956699\n",
       "2000-01-29    1.315865\n",
       "2000-01-30    1.498927\n",
       "2000-01-31    1.523367\n",
       "2000-02-01    1.883411\n",
       "2000-02-02    2.123618\n",
       "2000-02-03    1.943752\n",
       "2000-02-04    1.779760\n",
       "2000-02-05    1.781678\n",
       "2000-02-06    2.020606\n",
       "                ...   \n",
       "2002-09-05    1.588590\n",
       "2002-09-06    1.452934\n",
       "2002-09-07    1.614431\n",
       "2002-09-08    1.605148\n",
       "2002-09-09    1.494452\n",
       "2002-09-10    1.359194\n",
       "2002-09-11    1.318504\n",
       "2002-09-12    1.267912\n",
       "2002-09-13    1.019576\n",
       "2002-09-14    1.116757\n",
       "2002-09-15    1.106239\n",
       "2002-09-16    0.996973\n",
       "2002-09-17    0.661531\n",
       "2002-09-18    0.531250\n",
       "2002-09-19    0.398679\n",
       "2002-09-20    0.513161\n",
       "2002-09-21    0.306738\n",
       "2002-09-22   -0.136785\n",
       "2002-09-23   -0.031068\n",
       "2002-09-24   -0.271677\n",
       "2002-09-25   -0.318890\n",
       "2002-09-26   -0.318157\n",
       "2002-09-27   -0.444920\n",
       "2002-09-28   -0.603798\n",
       "2002-09-29   -0.622521\n",
       "2002-09-30   -0.598372\n",
       "2002-10-01   -0.660057\n",
       "2002-10-02   -0.750029\n",
       "2002-10-03   -0.834275\n",
       "2002-10-04   -0.762241\n",
       "Freq: D, Length: 1001, dtype: float64"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "transformed = ts.groupby(key).transform(zscore)\n",
    "transformed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = ts.groupby(key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000    0.373170\n",
       "2001    0.265318\n",
       "2002    0.426585\n",
       "dtype: float64"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000    0.160837\n",
       "2001    0.252933\n",
       "2002    0.190707\n",
       "dtype: float64"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.std()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped_trans = transformed.groupby(key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000    1.0\n",
       "2001    1.0\n",
       "2002    1.0\n",
       "dtype: float64"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped_trans.std()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0xe8352b0>"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n/H9vqPDyLaFM0QAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0xf595320>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "compare = pd.DataFrame({'Original': ts, 'Transformed': transformed})\n",
    "compare.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "data_range = lambda x: x.max() - x.min()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-08    0.673745\n",
       "2000-01-09    0.673745\n",
       "2000-01-10    0.673745\n",
       "2000-01-11    0.673745\n",
       "2000-01-12    0.673745\n",
       "2000-01-13    0.673745\n",
       "2000-01-14    0.673745\n",
       "2000-01-15    0.673745\n",
       "2000-01-16    0.673745\n",
       "2000-01-17    0.673745\n",
       "2000-01-18    0.673745\n",
       "2000-01-19    0.673745\n",
       "2000-01-20    0.673745\n",
       "2000-01-21    0.673745\n",
       "2000-01-22    0.673745\n",
       "2000-01-23    0.673745\n",
       "2000-01-24    0.673745\n",
       "2000-01-25    0.673745\n",
       "2000-01-26    0.673745\n",
       "2000-01-27    0.673745\n",
       "2000-01-28    0.673745\n",
       "2000-01-29    0.673745\n",
       "2000-01-30    0.673745\n",
       "2000-01-31    0.673745\n",
       "2000-02-01    0.673745\n",
       "2000-02-02    0.673745\n",
       "2000-02-03    0.673745\n",
       "2000-02-04    0.673745\n",
       "2000-02-05    0.673745\n",
       "2000-02-06    0.673745\n",
       "                ...   \n",
       "2002-09-05    0.799322\n",
       "2002-09-06    0.799322\n",
       "2002-09-07    0.799322\n",
       "2002-09-08    0.799322\n",
       "2002-09-09    0.799322\n",
       "2002-09-10    0.799322\n",
       "2002-09-11    0.799322\n",
       "2002-09-12    0.799322\n",
       "2002-09-13    0.799322\n",
       "2002-09-14    0.799322\n",
       "2002-09-15    0.799322\n",
       "2002-09-16    0.799322\n",
       "2002-09-17    0.799322\n",
       "2002-09-18    0.799322\n",
       "2002-09-19    0.799322\n",
       "2002-09-20    0.799322\n",
       "2002-09-21    0.799322\n",
       "2002-09-22    0.799322\n",
       "2002-09-23    0.799322\n",
       "2002-09-24    0.799322\n",
       "2002-09-25    0.799322\n",
       "2002-09-26    0.799322\n",
       "2002-09-27    0.799322\n",
       "2002-09-28    0.799322\n",
       "2002-09-29    0.799322\n",
       "2002-09-30    0.799322\n",
       "2002-10-01    0.799322\n",
       "2002-10-02    0.799322\n",
       "2002-10-03    0.799322\n",
       "2002-10-04    0.799322\n",
       "Freq: D, Length: 1001, dtype: float64"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.groupby(key).transform(data_range)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-01-08    0.673745\n",
       "2000-01-09    0.673745\n",
       "2000-01-10    0.673745\n",
       "2000-01-11    0.673745\n",
       "2000-01-12    0.673745\n",
       "2000-01-13    0.673745\n",
       "2000-01-14    0.673745\n",
       "2000-01-15    0.673745\n",
       "2000-01-16    0.673745\n",
       "2000-01-17    0.673745\n",
       "2000-01-18    0.673745\n",
       "2000-01-19    0.673745\n",
       "2000-01-20    0.673745\n",
       "2000-01-21    0.673745\n",
       "2000-01-22    0.673745\n",
       "2000-01-23    0.673745\n",
       "2000-01-24    0.673745\n",
       "2000-01-25    0.673745\n",
       "2000-01-26    0.673745\n",
       "2000-01-27    0.673745\n",
       "2000-01-28    0.673745\n",
       "2000-01-29    0.673745\n",
       "2000-01-30    0.673745\n",
       "2000-01-31    0.673745\n",
       "2000-02-01    0.673745\n",
       "2000-02-02    0.673745\n",
       "2000-02-03    0.673745\n",
       "2000-02-04    0.673745\n",
       "2000-02-05    0.673745\n",
       "2000-02-06    0.673745\n",
       "                ...   \n",
       "2002-09-05    0.799322\n",
       "2002-09-06    0.799322\n",
       "2002-09-07    0.799322\n",
       "2002-09-08    0.799322\n",
       "2002-09-09    0.799322\n",
       "2002-09-10    0.799322\n",
       "2002-09-11    0.799322\n",
       "2002-09-12    0.799322\n",
       "2002-09-13    0.799322\n",
       "2002-09-14    0.799322\n",
       "2002-09-15    0.799322\n",
       "2002-09-16    0.799322\n",
       "2002-09-17    0.799322\n",
       "2002-09-18    0.799322\n",
       "2002-09-19    0.799322\n",
       "2002-09-20    0.799322\n",
       "2002-09-21    0.799322\n",
       "2002-09-22    0.799322\n",
       "2002-09-23    0.799322\n",
       "2002-09-24    0.799322\n",
       "2002-09-25    0.799322\n",
       "2002-09-26    0.799322\n",
       "2002-09-27    0.799322\n",
       "2002-09-28    0.799322\n",
       "2002-09-29    0.799322\n",
       "2002-09-30    0.799322\n",
       "2002-10-01    0.799322\n",
       "2002-10-02    0.799322\n",
       "2002-10-03    0.799322\n",
       "2002-10-04    0.799322\n",
       "Freq: D, Length: 1001, dtype: float64"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.groupby(key).transform('max') - ts.groupby(key).transform('min')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another common data transform is to replace missing data with the group mean."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.828127</td>\n",
       "      <td>-0.110294</td>\n",
       "      <td>0.035183</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.027962</td>\n",
       "      <td>-0.060075</td>\n",
       "      <td>-0.458134</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.004339</td>\n",
       "      <td>0.005199</td>\n",
       "      <td>-0.842601</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.081081</td>\n",
       "      <td>-0.607193</td>\n",
       "      <td>-1.168593</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.058312</td>\n",
       "      <td>-1.303463</td>\n",
       "      <td>-1.633475</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.247164</td>\n",
       "      <td>0.706189</td>\n",
       "      <td>-0.499013</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>0.835416</td>\n",
       "      <td>-1.240551</td>\n",
       "      <td>-0.705808</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>0.922992</td>\n",
       "      <td>-1.361350</td>\n",
       "      <td>-2.774647</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>0.442373</td>\n",
       "      <td>-1.421477</td>\n",
       "      <td>-1.532760</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>-1.218626</td>\n",
       "      <td>-1.069070</td>\n",
       "      <td>-0.111141</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>-0.539695</td>\n",
       "      <td>1.605281</td>\n",
       "      <td>1.009351</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>0.652668</td>\n",
       "      <td>-0.779819</td>\n",
       "      <td>-0.300812</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>1.248701</td>\n",
       "      <td>0.334853</td>\n",
       "      <td>-0.608131</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>1.288052</td>\n",
       "      <td>-0.745468</td>\n",
       "      <td>-0.084383</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>0.898373</td>\n",
       "      <td>0.737381</td>\n",
       "      <td>-0.603305</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>0.021726</td>\n",
       "      <td>-1.075966</td>\n",
       "      <td>2.478926</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>0.037722</td>\n",
       "      <td>1.730717</td>\n",
       "      <td>0.509116</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>1.266556</td>\n",
       "      <td>1.597435</td>\n",
       "      <td>-0.947602</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>-0.487010</td>\n",
       "      <td>1.019425</td>\n",
       "      <td>-1.595519</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>-0.371871</td>\n",
       "      <td>-0.076881</td>\n",
       "      <td>-0.406905</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>0.885168</td>\n",
       "      <td>1.484506</td>\n",
       "      <td>0.504318</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>1.565723</td>\n",
       "      <td>-0.679566</td>\n",
       "      <td>-0.383199</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>-0.548021</td>\n",
       "      <td>-3.406284</td>\n",
       "      <td>-1.112583</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>-0.308757</td>\n",
       "      <td>0.370648</td>\n",
       "      <td>-1.516904</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>-1.056791</td>\n",
       "      <td>0.516554</td>\n",
       "      <td>-0.167072</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>0.550842</td>\n",
       "      <td>0.387992</td>\n",
       "      <td>0.771594</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>0.321925</td>\n",
       "      <td>1.569165</td>\n",
       "      <td>-1.024612</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>0.736870</td>\n",
       "      <td>-1.172039</td>\n",
       "      <td>-0.451927</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>1.212018</td>\n",
       "      <td>-0.866973</td>\n",
       "      <td>-1.208125</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>-0.948226</td>\n",
       "      <td>-1.032819</td>\n",
       "      <td>-0.093462</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>970</th>\n",
       "      <td>1.881078</td>\n",
       "      <td>-0.781257</td>\n",
       "      <td>-2.361841</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>971</th>\n",
       "      <td>0.542197</td>\n",
       "      <td>-0.906827</td>\n",
       "      <td>0.047851</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>972</th>\n",
       "      <td>-0.040906</td>\n",
       "      <td>0.342534</td>\n",
       "      <td>0.141210</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>973</th>\n",
       "      <td>0.064292</td>\n",
       "      <td>0.818153</td>\n",
       "      <td>0.253456</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>974</th>\n",
       "      <td>-0.051890</td>\n",
       "      <td>2.050634</td>\n",
       "      <td>0.600088</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>975</th>\n",
       "      <td>-0.206901</td>\n",
       "      <td>-0.295143</td>\n",
       "      <td>-0.699548</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>976</th>\n",
       "      <td>-0.095685</td>\n",
       "      <td>1.010718</td>\n",
       "      <td>-0.351998</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>977</th>\n",
       "      <td>-0.963164</td>\n",
       "      <td>0.514926</td>\n",
       "      <td>1.307137</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>978</th>\n",
       "      <td>-0.331447</td>\n",
       "      <td>0.024692</td>\n",
       "      <td>0.987817</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>979</th>\n",
       "      <td>0.363296</td>\n",
       "      <td>0.055889</td>\n",
       "      <td>0.222069</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>980</th>\n",
       "      <td>-2.330593</td>\n",
       "      <td>-0.623006</td>\n",
       "      <td>0.740125</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>981</th>\n",
       "      <td>-1.709674</td>\n",
       "      <td>0.537182</td>\n",
       "      <td>-0.728226</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>982</th>\n",
       "      <td>-1.999581</td>\n",
       "      <td>1.024241</td>\n",
       "      <td>0.389662</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>983</th>\n",
       "      <td>-0.101936</td>\n",
       "      <td>-0.487496</td>\n",
       "      <td>1.349537</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>984</th>\n",
       "      <td>-0.960504</td>\n",
       "      <td>-1.075182</td>\n",
       "      <td>0.400736</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>985</th>\n",
       "      <td>-1.738227</td>\n",
       "      <td>-0.003839</td>\n",
       "      <td>2.204468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>986</th>\n",
       "      <td>0.253496</td>\n",
       "      <td>-1.034156</td>\n",
       "      <td>-0.519874</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>987</th>\n",
       "      <td>-0.397488</td>\n",
       "      <td>-0.439153</td>\n",
       "      <td>-0.284092</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>988</th>\n",
       "      <td>1.839780</td>\n",
       "      <td>0.460715</td>\n",
       "      <td>-0.537275</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>989</th>\n",
       "      <td>-1.391903</td>\n",
       "      <td>-0.832412</td>\n",
       "      <td>-0.697537</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>990</th>\n",
       "      <td>0.111827</td>\n",
       "      <td>0.871810</td>\n",
       "      <td>-2.185444</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>991</th>\n",
       "      <td>-0.480684</td>\n",
       "      <td>0.179963</td>\n",
       "      <td>0.845224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>992</th>\n",
       "      <td>0.825410</td>\n",
       "      <td>-0.723115</td>\n",
       "      <td>0.932190</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>993</th>\n",
       "      <td>0.979648</td>\n",
       "      <td>0.758937</td>\n",
       "      <td>1.579080</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>994</th>\n",
       "      <td>1.652681</td>\n",
       "      <td>-1.966458</td>\n",
       "      <td>-0.437036</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>995</th>\n",
       "      <td>-1.078268</td>\n",
       "      <td>-0.203733</td>\n",
       "      <td>0.288298</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>996</th>\n",
       "      <td>0.217226</td>\n",
       "      <td>-0.209543</td>\n",
       "      <td>-0.128268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>997</th>\n",
       "      <td>1.177620</td>\n",
       "      <td>0.471514</td>\n",
       "      <td>-1.479206</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>998</th>\n",
       "      <td>-0.416937</td>\n",
       "      <td>0.720835</td>\n",
       "      <td>1.069728</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>999</th>\n",
       "      <td>-2.292125</td>\n",
       "      <td>-0.042686</td>\n",
       "      <td>0.270454</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1000 rows × 3 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "            A         B         C\n",
       "0    0.828127 -0.110294  0.035183\n",
       "1    1.027962 -0.060075 -0.458134\n",
       "2   -0.004339  0.005199 -0.842601\n",
       "3   -0.081081 -0.607193 -1.168593\n",
       "4    1.058312 -1.303463 -1.633475\n",
       "5    0.247164  0.706189 -0.499013\n",
       "6    0.835416 -1.240551 -0.705808\n",
       "7    0.922992 -1.361350 -2.774647\n",
       "8    0.442373 -1.421477 -1.532760\n",
       "9   -1.218626 -1.069070 -0.111141\n",
       "10  -0.539695  1.605281  1.009351\n",
       "11   0.652668 -0.779819 -0.300812\n",
       "12   1.248701  0.334853 -0.608131\n",
       "13   1.288052 -0.745468 -0.084383\n",
       "14   0.898373  0.737381 -0.603305\n",
       "15   0.021726 -1.075966  2.478926\n",
       "16   0.037722  1.730717  0.509116\n",
       "17   1.266556  1.597435 -0.947602\n",
       "18  -0.487010  1.019425 -1.595519\n",
       "19  -0.371871 -0.076881 -0.406905\n",
       "20   0.885168  1.484506  0.504318\n",
       "21   1.565723 -0.679566 -0.383199\n",
       "22  -0.548021 -3.406284 -1.112583\n",
       "23  -0.308757  0.370648 -1.516904\n",
       "24  -1.056791  0.516554 -0.167072\n",
       "25   0.550842  0.387992  0.771594\n",
       "26   0.321925  1.569165 -1.024612\n",
       "27   0.736870 -1.172039 -0.451927\n",
       "28   1.212018 -0.866973 -1.208125\n",
       "29  -0.948226 -1.032819 -0.093462\n",
       "..        ...       ...       ...\n",
       "970  1.881078 -0.781257 -2.361841\n",
       "971  0.542197 -0.906827  0.047851\n",
       "972 -0.040906  0.342534  0.141210\n",
       "973  0.064292  0.818153  0.253456\n",
       "974 -0.051890  2.050634  0.600088\n",
       "975 -0.206901 -0.295143 -0.699548\n",
       "976 -0.095685  1.010718 -0.351998\n",
       "977 -0.963164  0.514926  1.307137\n",
       "978 -0.331447  0.024692  0.987817\n",
       "979  0.363296  0.055889  0.222069\n",
       "980 -2.330593 -0.623006  0.740125\n",
       "981 -1.709674  0.537182 -0.728226\n",
       "982 -1.999581  1.024241  0.389662\n",
       "983 -0.101936 -0.487496  1.349537\n",
       "984 -0.960504 -1.075182  0.400736\n",
       "985 -1.738227 -0.003839  2.204468\n",
       "986  0.253496 -1.034156 -0.519874\n",
       "987 -0.397488 -0.439153 -0.284092\n",
       "988  1.839780  0.460715 -0.537275\n",
       "989 -1.391903 -0.832412 -0.697537\n",
       "990  0.111827  0.871810 -2.185444\n",
       "991 -0.480684  0.179963  0.845224\n",
       "992  0.825410 -0.723115  0.932190\n",
       "993  0.979648  0.758937  1.579080\n",
       "994  1.652681 -1.966458 -0.437036\n",
       "995 -1.078268 -0.203733  0.288298\n",
       "996  0.217226 -0.209543 -0.128268\n",
       "997  1.177620  0.471514 -1.479206\n",
       "998 -0.416937  0.720835  1.069728\n",
       "999 -2.292125 -0.042686  0.270454\n",
       "\n",
       "[1000 rows x 3 columns]"
      ]
     },
     "execution_count": 126,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df=pd.DataFrame(np.random.randn(3000).reshape(1000,3),columns=['A','B','C'])\n",
    "data_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2, 2, 0, 1, 3, 3, 3, 0, 3, 3, 0, 0, 0, 3, 1, 3, 1, 3, 1, 3, 0, 2,\n",
       "       1, 2, 0, 1, 3, 0, 0, 1, 3, 0, 0, 0, 2, 3, 0, 2, 0, 3, 0, 1, 1, 0,\n",
       "       0, 0, 3, 0, 0, 1, 0, 1, 2, 0, 1, 1, 2, 3, 0, 1, 3, 2, 2, 2, 3, 0,\n",
       "       2, 3, 0, 3, 0, 2, 1, 0, 0, 1, 2, 0, 2, 1, 0, 2, 0, 0, 0, 0, 3, 1,\n",
       "       1, 2, 1, 2, 3, 3, 1, 2, 3, 0, 3, 1, 1, 2, 1, 1, 2, 1, 2, 2, 2, 0,\n",
       "       1, 3, 2, 0, 3, 2, 1, 0, 2, 0, 1, 2, 1, 1, 1, 3, 3, 3, 3, 3, 3, 2,\n",
       "       3, 2, 1, 1, 3, 0, 0, 1, 1, 1, 3, 0, 2, 0, 3, 0, 3, 1, 2, 3, 1, 0,\n",
       "       1, 3, 0, 1, 2, 1, 0, 1, 0, 2, 3, 0, 3, 1, 1, 2, 2, 1, 3, 2, 1, 1,\n",
       "       3, 2, 0, 1, 3, 2, 2, 3, 3, 3, 2, 2, 2, 3, 1, 0, 1, 0, 0, 2, 0, 2,\n",
       "       2, 2, 1, 2, 2, 0, 0, 1, 2, 1, 0, 0, 3, 2, 3, 3, 3, 3, 1, 0, 2, 3,\n",
       "       3, 0, 2, 3, 2, 1, 2, 2, 3, 0, 0, 0, 1, 3, 3, 2, 1, 0, 3, 1, 1, 3,\n",
       "       3, 0, 3, 3, 0, 2, 3, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 0, 3, 0, 3, 3,\n",
       "       2, 2, 1, 0, 1, 2, 3, 2, 1, 0, 0, 3, 2, 3, 2, 1, 2, 1, 1, 1, 2, 3,\n",
       "       0, 3, 2, 2, 2, 2, 3, 2, 0, 0, 2, 1, 2, 2, 1, 3, 2, 0, 2, 2, 2, 2,\n",
       "       1, 1, 0, 3, 0, 3, 0, 3, 2, 0, 3, 1, 0, 2, 3, 0, 2, 3, 0, 2, 0, 1,\n",
       "       1, 3, 2, 3, 1, 1, 3, 3, 0, 1, 2, 2, 2, 1, 1, 1, 3, 3, 3, 1, 3, 3,\n",
       "       2, 3, 3, 3, 2, 0, 0, 0, 3, 0, 2, 2, 1, 1, 3, 1, 2, 2, 0, 2, 0, 3,\n",
       "       1, 1, 2, 0, 0, 3, 1, 2, 1, 3, 2, 1, 1, 3, 1, 1, 3, 1, 2, 1, 3, 0,\n",
       "       1, 2, 3, 1, 0, 1, 3, 0, 2, 3, 3, 2, 1, 3, 2, 0, 2, 3, 2, 1, 0, 2,\n",
       "       1, 3, 3, 1, 3, 3, 3, 2, 1, 0, 1, 2, 0, 0, 2, 2, 1, 1, 0, 0, 3, 0,\n",
       "       3, 0, 0, 1, 2, 2, 3, 2, 0, 3, 0, 0, 1, 3, 0, 2, 0, 1, 3, 1, 2, 0,\n",
       "       0, 1, 2, 1, 0, 0, 2, 3, 2, 1, 3, 2, 3, 0, 1, 3, 0, 0, 2, 2, 0, 2,\n",
       "       0, 1, 2, 0, 2, 0, 2, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 3, 3, 1, 1, 3,\n",
       "       0, 0, 2, 0, 3, 0, 0, 2, 1, 3, 2, 0, 2, 2, 3, 0, 0, 2, 2, 0, 2, 3,\n",
       "       0, 3, 3, 0, 1, 0, 1, 2, 2, 1, 2, 3, 1, 3, 0, 0, 2, 3, 2, 2, 0, 1,\n",
       "       3, 3, 3, 3, 0, 2, 2, 0, 3, 2, 0, 3, 0, 2, 3, 3, 2, 1, 3, 2, 2, 1,\n",
       "       3, 2, 1, 1, 1, 3, 2, 2, 1, 3, 1, 2, 3, 2, 2, 0, 0, 2, 1, 1, 2, 2,\n",
       "       3, 0, 2, 0, 3, 3, 3, 0, 0, 3, 1, 2, 1, 3, 2, 3, 2, 3, 3, 3, 1, 3,\n",
       "       3, 3, 3, 1, 3, 1, 0, 1, 3, 3, 3, 3, 2, 3, 3, 0, 1, 0, 0, 3, 3, 1,\n",
       "       1, 0, 2, 3, 3, 0, 0, 1, 2, 3, 3, 0, 3, 1, 3, 3, 1, 2, 1, 1, 0, 0,\n",
       "       1, 1, 1, 0, 3, 1, 3, 0, 0, 0, 1, 3, 2, 1, 2, 3, 3, 3, 3, 1, 2, 3,\n",
       "       1, 3, 1, 1, 2, 1, 3, 2, 2, 3, 1, 0, 3, 1, 2, 1, 1, 3, 3, 2, 1, 3,\n",
       "       1, 1, 2, 3, 3, 0, 1, 0, 2, 0, 3, 0, 3, 1, 1, 1, 2, 0, 2, 3, 3, 1,\n",
       "       3, 3, 1, 1, 0, 3, 3, 2, 0, 1, 2, 0, 1, 1, 2, 2, 0, 3, 0, 2, 3, 0,\n",
       "       0, 3, 1, 0, 0, 3, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 1, 3, 2, 3, 2, 3,\n",
       "       0, 0, 2, 3, 1, 1, 2, 0, 0, 3, 3, 3, 0, 1, 1, 1, 3, 2, 0, 2, 3, 1,\n",
       "       2, 1, 3, 1, 0, 0, 1, 2, 3, 2, 2, 1, 0, 2, 1, 3, 3, 0, 2, 2, 2, 2,\n",
       "       1, 1, 2, 0, 1, 2, 1, 3, 2, 1, 2, 0, 1, 0, 3, 0, 2, 3, 3, 1, 3, 2,\n",
       "       3, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 3, 1, 0, 1, 1, 3, 1, 0, 3,\n",
       "       1, 2, 0, 3, 2, 3, 0, 3, 0, 2, 2, 1, 3, 0, 0, 1, 1, 3, 1, 2, 3, 1,\n",
       "       0, 2, 2, 1, 3, 3, 1, 2, 3, 0, 2, 2, 2, 0, 2, 3, 3, 2, 1, 0, 2, 0,\n",
       "       2, 2, 3, 3, 2, 3, 2, 3, 3, 1, 1, 1, 1, 1, 2, 2, 3, 3, 2, 0, 3, 3,\n",
       "       3, 3, 1, 0, 3, 2, 0, 2, 0, 3, 3, 3, 1, 0, 3, 1, 2, 2, 0, 0, 3, 3,\n",
       "       3, 3, 1, 3, 1, 1, 1, 1, 1, 1, 2, 0, 3, 0, 0, 3, 0, 0, 0, 2, 0, 0,\n",
       "       1, 0, 3, 2, 0, 1, 0, 1, 2, 3, 1, 1, 2, 0, 3, 1, 0, 2, 1, 2, 1, 2,\n",
       "       3, 3, 3, 0, 2, 1, 0, 2, 1, 1])"
      ]
     },
     "execution_count": 130,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "countries = np.array(['US', 'UK', 'GR', 'JP'])\n",
    "np.random.randint(0, 4, 1000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['US', 'GR', 'JP', 'US', 'GR', 'UK', 'US', 'GR', 'UK', 'GR', 'UK',\n",
       "       'GR', 'GR', 'UK', 'UK', 'US', 'US', 'JP', 'US', 'JP', 'GR', 'GR',\n",
       "       'US', 'JP', 'US', 'UK', 'JP', 'JP', 'JP', 'US', 'GR', 'UK', 'JP',\n",
       "       'UK', 'UK', 'US', 'GR', 'JP', 'JP', 'US', 'JP', 'UK', 'UK', 'JP',\n",
       "       'JP', 'JP', 'US', 'GR', 'US', 'US', 'US', 'JP', 'GR', 'JP', 'US',\n",
       "       'UK', 'US', 'JP', 'JP', 'GR', 'UK', 'GR', 'GR', 'JP', 'GR', 'GR',\n",
       "       'GR', 'GR', 'GR', 'UK', 'JP', 'US', 'UK', 'UK', 'US', 'JP', 'JP',\n",
       "       'UK', 'US', 'US', 'US', 'US', 'US', 'UK', 'GR', 'UK', 'JP', 'US',\n",
       "       'GR', 'UK', 'GR', 'US', 'JP', 'JP', 'US', 'JP', 'US', 'US', 'GR',\n",
       "       'JP', 'GR', 'UK', 'US', 'JP', 'UK', 'JP', 'JP', 'GR', 'US', 'US',\n",
       "       'JP', 'GR', 'UK', 'JP', 'UK', 'GR', 'UK', 'GR', 'JP', 'GR', 'GR',\n",
       "       'JP', 'US', 'JP', 'US', 'UK', 'GR', 'JP', 'UK', 'JP', 'GR', 'UK',\n",
       "       'JP', 'JP', 'US', 'GR', 'US', 'US', 'JP', 'GR', 'GR', 'JP', 'US',\n",
       "       'US', 'US', 'US', 'US', 'JP', 'GR', 'UK', 'US', 'US', 'JP', 'JP',\n",
       "       'US', 'US', 'JP', 'GR', 'JP', 'JP', 'UK', 'UK', 'GR', 'US', 'UK',\n",
       "       'US', 'US', 'US', 'JP', 'UK', 'US', 'US', 'JP', 'UK', 'JP', 'UK',\n",
       "       'US', 'GR', 'UK', 'UK', 'GR', 'UK', 'GR', 'GR', 'JP', 'JP', 'UK',\n",
       "       'GR', 'US', 'JP', 'JP', 'UK', 'UK', 'UK', 'GR', 'US', 'US', 'JP',\n",
       "       'GR', 'JP', 'UK', 'JP', 'GR', 'UK', 'UK', 'UK', 'GR', 'JP', 'JP',\n",
       "       'GR', 'US', 'JP', 'US', 'US', 'GR', 'JP', 'JP', 'UK', 'JP', 'JP',\n",
       "       'GR', 'US', 'UK', 'GR', 'GR', 'US', 'UK', 'JP', 'GR', 'UK', 'GR',\n",
       "       'GR', 'GR', 'GR', 'US', 'GR', 'GR', 'JP', 'JP', 'GR', 'UK', 'GR',\n",
       "       'JP', 'US', 'JP', 'JP', 'GR', 'US', 'US', 'GR', 'GR', 'GR', 'UK',\n",
       "       'US', 'GR', 'JP', 'GR', 'UK', 'GR', 'GR', 'UK', 'GR', 'US', 'US',\n",
       "       'JP', 'US', 'JP', 'UK', 'JP', 'GR', 'UK', 'UK', 'JP', 'UK', 'US',\n",
       "       'UK', 'UK', 'JP', 'GR', 'UK', 'US', 'UK', 'GR', 'US', 'GR', 'GR',\n",
       "       'UK', 'UK', 'UK', 'GR', 'US', 'US', 'GR', 'JP', 'JP', 'JP', 'UK',\n",
       "       'GR', 'GR', 'JP', 'GR', 'JP', 'US', 'UK', 'JP', 'UK', 'UK', 'UK',\n",
       "       'JP', 'JP', 'UK', 'US', 'GR', 'JP', 'UK', 'GR', 'GR', 'GR', 'UK',\n",
       "       'GR', 'GR', 'UK', 'US', 'GR', 'GR', 'JP', 'GR', 'GR', 'GR', 'US',\n",
       "       'JP', 'GR', 'US', 'JP', 'US', 'JP', 'US', 'JP', 'US', 'US', 'GR',\n",
       "       'US', 'JP', 'US', 'JP', 'UK', 'GR', 'UK', 'UK', 'GR', 'US', 'US',\n",
       "       'UK', 'US', 'UK', 'US', 'GR', 'UK', 'GR', 'US', 'GR', 'US', 'US',\n",
       "       'US', 'JP', 'UK', 'UK', 'UK', 'US', 'US', 'UK', 'JP', 'GR', 'GR',\n",
       "       'GR', 'US', 'US', 'GR', 'GR', 'US', 'GR', 'US', 'UK', 'GR', 'JP',\n",
       "       'JP', 'JP', 'US', 'US', 'JP', 'US', 'JP', 'UK', 'US', 'GR', 'GR',\n",
       "       'US', 'JP', 'US', 'GR', 'GR', 'JP', 'US', 'JP', 'US', 'GR', 'US',\n",
       "       'US', 'GR', 'GR', 'UK', 'JP', 'GR', 'US', 'JP', 'UK', 'UK', 'GR',\n",
       "       'GR', 'US', 'JP', 'JP', 'US', 'JP', 'UK', 'UK', 'JP', 'JP', 'GR',\n",
       "       'JP', 'UK', 'UK', 'GR', 'US', 'UK', 'JP', 'US', 'UK', 'GR', 'GR',\n",
       "       'JP', 'GR', 'GR', 'JP', 'GR', 'US', 'UK', 'UK', 'US', 'US', 'UK',\n",
       "       'JP', 'GR', 'US', 'UK', 'US', 'US', 'US', 'GR', 'UK', 'US', 'JP',\n",
       "       'UK', 'UK', 'JP', 'JP', 'JP', 'JP', 'UK', 'UK', 'GR', 'US', 'JP',\n",
       "       'US', 'GR', 'GR', 'UK', 'GR', 'UK', 'US', 'UK', 'JP', 'GR', 'UK',\n",
       "       'JP', 'GR', 'GR', 'US', 'JP', 'JP', 'GR', 'JP', 'JP', 'US', 'JP',\n",
       "       'JP', 'GR', 'JP', 'GR', 'GR', 'GR', 'US', 'US', 'UK', 'US', 'UK',\n",
       "       'US', 'JP', 'US', 'GR', 'US', 'JP', 'JP', 'US', 'UK', 'UK', 'JP',\n",
       "       'UK', 'GR', 'GR', 'GR', 'UK', 'JP', 'US', 'UK', 'UK', 'UK', 'UK',\n",
       "       'UK', 'GR', 'UK', 'UK', 'US', 'GR', 'GR', 'US', 'US', 'JP', 'JP',\n",
       "       'UK', 'JP', 'JP', 'UK', 'UK', 'UK', 'JP', 'UK', 'UK', 'UK', 'US',\n",
       "       'UK', 'JP', 'US', 'US', 'US', 'US', 'UK', 'UK', 'JP', 'US', 'JP',\n",
       "       'UK', 'US', 'JP', 'JP', 'UK', 'UK', 'GR', 'GR', 'GR', 'US', 'US',\n",
       "       'GR', 'GR', 'JP', 'UK', 'GR', 'UK', 'US', 'US', 'UK', 'UK', 'UK',\n",
       "       'US', 'US', 'JP', 'GR', 'UK', 'JP', 'UK', 'UK', 'GR', 'UK', 'UK',\n",
       "       'GR', 'JP', 'US', 'JP', 'GR', 'US', 'JP', 'US', 'GR', 'UK', 'JP',\n",
       "       'GR', 'US', 'UK', 'UK', 'GR', 'JP', 'GR', 'GR', 'GR', 'US', 'UK',\n",
       "       'US', 'US', 'JP', 'GR', 'GR', 'GR', 'GR', 'UK', 'GR', 'GR', 'UK',\n",
       "       'JP', 'GR', 'JP', 'JP', 'US', 'UK', 'UK', 'UK', 'GR', 'US', 'GR',\n",
       "       'GR', 'JP', 'US', 'UK', 'UK', 'GR', 'US', 'US', 'GR', 'JP', 'GR',\n",
       "       'GR', 'GR', 'JP', 'US', 'UK', 'US', 'UK', 'UK', 'US', 'GR', 'UK',\n",
       "       'JP', 'US', 'GR', 'US', 'JP', 'UK', 'GR', 'US', 'JP', 'GR', 'UK',\n",
       "       'JP', 'US', 'UK', 'UK', 'GR', 'JP', 'GR', 'GR', 'US', 'UK', 'JP',\n",
       "       'GR', 'UK', 'US', 'GR', 'JP', 'US', 'UK', 'GR', 'UK', 'JP', 'US',\n",
       "       'GR', 'JP', 'GR', 'JP', 'US', 'GR', 'JP', 'JP', 'JP', 'GR', 'US',\n",
       "       'GR', 'US', 'JP', 'JP', 'GR', 'JP', 'JP', 'GR', 'GR', 'UK', 'JP',\n",
       "       'US', 'JP', 'GR', 'US', 'US', 'JP', 'US', 'US', 'JP', 'JP', 'GR',\n",
       "       'GR', 'GR', 'GR', 'GR', 'JP', 'GR', 'UK', 'GR', 'US', 'GR', 'UK',\n",
       "       'UK', 'GR', 'JP', 'US', 'JP', 'US', 'UK', 'GR', 'US', 'GR', 'GR',\n",
       "       'UK', 'US', 'UK', 'JP', 'GR', 'GR', 'GR', 'UK', 'US', 'UK', 'UK',\n",
       "       'GR', 'US', 'GR', 'UK', 'US', 'JP', 'GR', 'GR', 'GR', 'GR', 'JP',\n",
       "       'UK', 'UK', 'US', 'JP', 'UK', 'UK', 'UK', 'JP', 'US', 'UK', 'GR',\n",
       "       'US', 'US', 'UK', 'US', 'GR', 'US', 'JP', 'US', 'UK', 'UK', 'US',\n",
       "       'JP', 'GR', 'US', 'GR', 'JP', 'US', 'UK', 'JP', 'GR', 'JP', 'UK',\n",
       "       'JP', 'JP', 'JP', 'UK', 'US', 'UK', 'JP', 'GR', 'US', 'JP', 'UK',\n",
       "       'US', 'JP', 'US', 'GR', 'JP', 'US', 'GR', 'GR', 'GR', 'UK', 'GR',\n",
       "       'GR', 'JP', 'GR', 'GR', 'GR', 'JP', 'GR', 'US', 'JP', 'US', 'UK',\n",
       "       'GR', 'GR', 'UK', 'JP', 'GR', 'JP', 'UK', 'US', 'US', 'GR', 'JP',\n",
       "       'US', 'UK', 'UK', 'US', 'UK', 'US', 'JP', 'GR', 'UK', 'GR', 'US',\n",
       "       'GR', 'JP', 'GR', 'GR', 'GR', 'US', 'US', 'UK', 'GR', 'GR', 'US',\n",
       "       'JP', 'US', 'UK', 'US', 'GR', 'GR', 'GR', 'US', 'JP', 'JP', 'GR',\n",
       "       'JP', 'GR', 'GR', 'GR', 'UK', 'UK', 'GR', 'GR', 'JP', 'JP', 'US',\n",
       "       'US', 'US', 'UK', 'GR', 'UK', 'UK', 'US', 'GR', 'JP', 'UK', 'JP',\n",
       "       'JP', 'JP', 'GR', 'JP', 'GR', 'UK', 'JP', 'US', 'GR', 'JP', 'UK',\n",
       "       'JP', 'JP', 'UK', 'JP', 'GR', 'GR', 'GR', 'UK', 'UK', 'GR', 'US',\n",
       "       'US', 'UK', 'UK', 'GR', 'UK', 'GR', 'GR', 'GR', 'GR', 'UK', 'US',\n",
       "       'US', 'UK', 'US', 'UK', 'GR', 'GR', 'JP', 'GR', 'JP', 'UK', 'GR',\n",
       "       'GR', 'JP', 'US', 'GR', 'UK', 'GR', 'JP', 'GR', 'UK', 'JP', 'US',\n",
       "       'GR', 'UK', 'US', 'JP', 'UK', 'GR', 'US', 'JP', 'US', 'UK', 'UK',\n",
       "       'UK', 'JP', 'US', 'UK', 'JP', 'US', 'JP', 'UK', 'JP', 'GR', 'UK',\n",
       "       'JP', 'US', 'GR', 'US', 'US', 'UK', 'UK', 'JP', 'GR', 'JP', 'UK',\n",
       "       'GR', 'JP', 'GR', 'GR', 'UK', 'GR', 'JP', 'JP', 'US', 'GR'],\n",
       "      dtype='<U2')"
      ]
     },
     "execution_count": 141,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "key = countries[np.random.randint(0, 4, 1000)]\n",
    "key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'GR': Int64Index([  5,  18,  26,  32,  33,  38,  45,  51,  56,  60,\n",
       "             ...\n",
       "             945, 949, 950, 961, 964, 973, 974, 979, 985, 994],\n",
       "            dtype='int64', length=235),\n",
       " 'JP': Int64Index([  1,   3,   6,  10,  11,  13,  20,  23,  27,  36,\n",
       "             ...\n",
       "             958, 975, 978, 980, 983, 986, 987, 988, 990, 998],\n",
       "            dtype='int64', length=251),\n",
       " 'UK': Int64Index([  4,   7,   8,   9,  14,  16,  17,  19,  21,  30,\n",
       "             ...\n",
       "             952, 960, 962, 963, 968, 972, 981, 982, 984, 993],\n",
       "            dtype='int64', length=250),\n",
       " 'US': Int64Index([  0,   2,  12,  15,  22,  24,  25,  28,  29,  35,\n",
       "             ...\n",
       "             971, 976, 977, 989, 991, 992, 995, 996, 997, 999],\n",
       "            dtype='int64', length=264)}"
      ]
     },
     "execution_count": 140,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped = data_df.groupby(key)\n",
    "grouped.groups"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "表示将data_df随机分成四类，这四类为countries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>GR</th>\n",
       "      <td>271</td>\n",
       "      <td>271</td>\n",
       "      <td>271</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>JP</th>\n",
       "      <td>256</td>\n",
       "      <td>256</td>\n",
       "      <td>256</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>UK</th>\n",
       "      <td>239</td>\n",
       "      <td>239</td>\n",
       "      <td>239</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>234</td>\n",
       "      <td>234</td>\n",
       "      <td>234</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      A    B    C\n",
       "GR  271  271  271\n",
       "JP  256  256  256\n",
       "UK  239  239  239\n",
       "US  234  234  234"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.count()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "f = lambda x: x.fillna(x.mean())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.828127</td>\n",
       "      <td>-0.110294</td>\n",
       "      <td>0.035183</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.027962</td>\n",
       "      <td>-0.060075</td>\n",
       "      <td>-0.458134</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.004339</td>\n",
       "      <td>0.005199</td>\n",
       "      <td>-0.842601</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.081081</td>\n",
       "      <td>-0.607193</td>\n",
       "      <td>-1.168593</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.058312</td>\n",
       "      <td>-1.303463</td>\n",
       "      <td>-1.633475</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.247164</td>\n",
       "      <td>0.706189</td>\n",
       "      <td>-0.499013</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>0.835416</td>\n",
       "      <td>-1.240551</td>\n",
       "      <td>-0.705808</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>0.922992</td>\n",
       "      <td>-1.361350</td>\n",
       "      <td>-2.774647</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>0.442373</td>\n",
       "      <td>-1.421477</td>\n",
       "      <td>-1.532760</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>-1.218626</td>\n",
       "      <td>-1.069070</td>\n",
       "      <td>-0.111141</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>-0.539695</td>\n",
       "      <td>1.605281</td>\n",
       "      <td>1.009351</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>0.652668</td>\n",
       "      <td>-0.779819</td>\n",
       "      <td>-0.300812</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>1.248701</td>\n",
       "      <td>0.334853</td>\n",
       "      <td>-0.608131</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>1.288052</td>\n",
       "      <td>-0.745468</td>\n",
       "      <td>-0.084383</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>0.898373</td>\n",
       "      <td>0.737381</td>\n",
       "      <td>-0.603305</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>0.021726</td>\n",
       "      <td>-1.075966</td>\n",
       "      <td>2.478926</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>0.037722</td>\n",
       "      <td>1.730717</td>\n",
       "      <td>0.509116</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>1.266556</td>\n",
       "      <td>1.597435</td>\n",
       "      <td>-0.947602</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>-0.487010</td>\n",
       "      <td>1.019425</td>\n",
       "      <td>-1.595519</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>-0.371871</td>\n",
       "      <td>-0.076881</td>\n",
       "      <td>-0.406905</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>0.885168</td>\n",
       "      <td>1.484506</td>\n",
       "      <td>0.504318</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>1.565723</td>\n",
       "      <td>-0.679566</td>\n",
       "      <td>-0.383199</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>-0.548021</td>\n",
       "      <td>-3.406284</td>\n",
       "      <td>-1.112583</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>-0.308757</td>\n",
       "      <td>0.370648</td>\n",
       "      <td>-1.516904</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>-1.056791</td>\n",
       "      <td>0.516554</td>\n",
       "      <td>-0.167072</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>0.550842</td>\n",
       "      <td>0.387992</td>\n",
       "      <td>0.771594</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>0.321925</td>\n",
       "      <td>1.569165</td>\n",
       "      <td>-1.024612</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>0.736870</td>\n",
       "      <td>-1.172039</td>\n",
       "      <td>-0.451927</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>1.212018</td>\n",
       "      <td>-0.866973</td>\n",
       "      <td>-1.208125</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>-0.948226</td>\n",
       "      <td>-1.032819</td>\n",
       "      <td>-0.093462</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>970</th>\n",
       "      <td>1.881078</td>\n",
       "      <td>-0.781257</td>\n",
       "      <td>-2.361841</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>971</th>\n",
       "      <td>0.542197</td>\n",
       "      <td>-0.906827</td>\n",
       "      <td>0.047851</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>972</th>\n",
       "      <td>-0.040906</td>\n",
       "      <td>0.342534</td>\n",
       "      <td>0.141210</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>973</th>\n",
       "      <td>0.064292</td>\n",
       "      <td>0.818153</td>\n",
       "      <td>0.253456</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>974</th>\n",
       "      <td>-0.051890</td>\n",
       "      <td>2.050634</td>\n",
       "      <td>0.600088</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>975</th>\n",
       "      <td>-0.206901</td>\n",
       "      <td>-0.295143</td>\n",
       "      <td>-0.699548</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>976</th>\n",
       "      <td>-0.095685</td>\n",
       "      <td>1.010718</td>\n",
       "      <td>-0.351998</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>977</th>\n",
       "      <td>-0.963164</td>\n",
       "      <td>0.514926</td>\n",
       "      <td>1.307137</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>978</th>\n",
       "      <td>-0.331447</td>\n",
       "      <td>0.024692</td>\n",
       "      <td>0.987817</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>979</th>\n",
       "      <td>0.363296</td>\n",
       "      <td>0.055889</td>\n",
       "      <td>0.222069</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>980</th>\n",
       "      <td>-2.330593</td>\n",
       "      <td>-0.623006</td>\n",
       "      <td>0.740125</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>981</th>\n",
       "      <td>-1.709674</td>\n",
       "      <td>0.537182</td>\n",
       "      <td>-0.728226</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>982</th>\n",
       "      <td>-1.999581</td>\n",
       "      <td>1.024241</td>\n",
       "      <td>0.389662</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>983</th>\n",
       "      <td>-0.101936</td>\n",
       "      <td>-0.487496</td>\n",
       "      <td>1.349537</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>984</th>\n",
       "      <td>-0.960504</td>\n",
       "      <td>-1.075182</td>\n",
       "      <td>0.400736</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>985</th>\n",
       "      <td>-1.738227</td>\n",
       "      <td>-0.003839</td>\n",
       "      <td>2.204468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>986</th>\n",
       "      <td>0.253496</td>\n",
       "      <td>-1.034156</td>\n",
       "      <td>-0.519874</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>987</th>\n",
       "      <td>-0.397488</td>\n",
       "      <td>-0.439153</td>\n",
       "      <td>-0.284092</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>988</th>\n",
       "      <td>1.839780</td>\n",
       "      <td>0.460715</td>\n",
       "      <td>-0.537275</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>989</th>\n",
       "      <td>-1.391903</td>\n",
       "      <td>-0.832412</td>\n",
       "      <td>-0.697537</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>990</th>\n",
       "      <td>0.111827</td>\n",
       "      <td>0.871810</td>\n",
       "      <td>-2.185444</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>991</th>\n",
       "      <td>-0.480684</td>\n",
       "      <td>0.179963</td>\n",
       "      <td>0.845224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>992</th>\n",
       "      <td>0.825410</td>\n",
       "      <td>-0.723115</td>\n",
       "      <td>0.932190</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>993</th>\n",
       "      <td>0.979648</td>\n",
       "      <td>0.758937</td>\n",
       "      <td>1.579080</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>994</th>\n",
       "      <td>1.652681</td>\n",
       "      <td>-1.966458</td>\n",
       "      <td>-0.437036</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>995</th>\n",
       "      <td>-1.078268</td>\n",
       "      <td>-0.203733</td>\n",
       "      <td>0.288298</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>996</th>\n",
       "      <td>0.217226</td>\n",
       "      <td>-0.209543</td>\n",
       "      <td>-0.128268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>997</th>\n",
       "      <td>1.177620</td>\n",
       "      <td>0.471514</td>\n",
       "      <td>-1.479206</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>998</th>\n",
       "      <td>-0.416937</td>\n",
       "      <td>0.720835</td>\n",
       "      <td>1.069728</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>999</th>\n",
       "      <td>-2.292125</td>\n",
       "      <td>-0.042686</td>\n",
       "      <td>0.270454</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1000 rows × 3 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "            A         B         C\n",
       "0    0.828127 -0.110294  0.035183\n",
       "1    1.027962 -0.060075 -0.458134\n",
       "2   -0.004339  0.005199 -0.842601\n",
       "3   -0.081081 -0.607193 -1.168593\n",
       "4    1.058312 -1.303463 -1.633475\n",
       "5    0.247164  0.706189 -0.499013\n",
       "6    0.835416 -1.240551 -0.705808\n",
       "7    0.922992 -1.361350 -2.774647\n",
       "8    0.442373 -1.421477 -1.532760\n",
       "9   -1.218626 -1.069070 -0.111141\n",
       "10  -0.539695  1.605281  1.009351\n",
       "11   0.652668 -0.779819 -0.300812\n",
       "12   1.248701  0.334853 -0.608131\n",
       "13   1.288052 -0.745468 -0.084383\n",
       "14   0.898373  0.737381 -0.603305\n",
       "15   0.021726 -1.075966  2.478926\n",
       "16   0.037722  1.730717  0.509116\n",
       "17   1.266556  1.597435 -0.947602\n",
       "18  -0.487010  1.019425 -1.595519\n",
       "19  -0.371871 -0.076881 -0.406905\n",
       "20   0.885168  1.484506  0.504318\n",
       "21   1.565723 -0.679566 -0.383199\n",
       "22  -0.548021 -3.406284 -1.112583\n",
       "23  -0.308757  0.370648 -1.516904\n",
       "24  -1.056791  0.516554 -0.167072\n",
       "25   0.550842  0.387992  0.771594\n",
       "26   0.321925  1.569165 -1.024612\n",
       "27   0.736870 -1.172039 -0.451927\n",
       "28   1.212018 -0.866973 -1.208125\n",
       "29  -0.948226 -1.032819 -0.093462\n",
       "..        ...       ...       ...\n",
       "970  1.881078 -0.781257 -2.361841\n",
       "971  0.542197 -0.906827  0.047851\n",
       "972 -0.040906  0.342534  0.141210\n",
       "973  0.064292  0.818153  0.253456\n",
       "974 -0.051890  2.050634  0.600088\n",
       "975 -0.206901 -0.295143 -0.699548\n",
       "976 -0.095685  1.010718 -0.351998\n",
       "977 -0.963164  0.514926  1.307137\n",
       "978 -0.331447  0.024692  0.987817\n",
       "979  0.363296  0.055889  0.222069\n",
       "980 -2.330593 -0.623006  0.740125\n",
       "981 -1.709674  0.537182 -0.728226\n",
       "982 -1.999581  1.024241  0.389662\n",
       "983 -0.101936 -0.487496  1.349537\n",
       "984 -0.960504 -1.075182  0.400736\n",
       "985 -1.738227 -0.003839  2.204468\n",
       "986  0.253496 -1.034156 -0.519874\n",
       "987 -0.397488 -0.439153 -0.284092\n",
       "988  1.839780  0.460715 -0.537275\n",
       "989 -1.391903 -0.832412 -0.697537\n",
       "990  0.111827  0.871810 -2.185444\n",
       "991 -0.480684  0.179963  0.845224\n",
       "992  0.825410 -0.723115  0.932190\n",
       "993  0.979648  0.758937  1.579080\n",
       "994  1.652681 -1.966458 -0.437036\n",
       "995 -1.078268 -0.203733  0.288298\n",
       "996  0.217226 -0.209543 -0.128268\n",
       "997  1.177620  0.471514 -1.479206\n",
       "998 -0.416937  0.720835  1.069728\n",
       "999 -2.292125 -0.042686  0.270454\n",
       "\n",
       "[1000 rows x 3 columns]"
      ]
     },
     "execution_count": 144,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "transformed = grouped.transform(f)\n",
    "transformed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "显然，对grouped执行transform后返回的结果和原dataframe是同构的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped_trans = transformed.groupby(key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>GR</th>\n",
       "      <td>-0.108906</td>\n",
       "      <td>0.024802</td>\n",
       "      <td>0.078695</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>JP</th>\n",
       "      <td>-0.051437</td>\n",
       "      <td>-0.070116</td>\n",
       "      <td>-0.013017</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>UK</th>\n",
       "      <td>-0.040967</td>\n",
       "      <td>0.042542</td>\n",
       "      <td>-0.029417</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>-0.045908</td>\n",
       "      <td>0.014057</td>\n",
       "      <td>-0.026218</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           A         B         C\n",
       "GR -0.108906  0.024802  0.078695\n",
       "JP -0.051437 -0.070116 -0.013017\n",
       "UK -0.040967  0.042542 -0.029417\n",
       "US -0.045908  0.014057 -0.026218"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>GR</th>\n",
       "      <td>-0.083690</td>\n",
       "      <td>-0.037037</td>\n",
       "      <td>0.044591</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>JP</th>\n",
       "      <td>0.019203</td>\n",
       "      <td>0.054376</td>\n",
       "      <td>0.009359</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>UK</th>\n",
       "      <td>-0.052340</td>\n",
       "      <td>-0.055207</td>\n",
       "      <td>-0.075634</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>-0.122903</td>\n",
       "      <td>0.053557</td>\n",
       "      <td>0.015501</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           A         B         C\n",
       "GR -0.083690 -0.037037  0.044591\n",
       "JP  0.019203  0.054376  0.009359\n",
       "UK -0.052340 -0.055207 -0.075634\n",
       "US -0.122903  0.053557  0.015501"
      ]
     },
     "execution_count": 147,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped_trans.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>GR</th>\n",
       "      <td>235</td>\n",
       "      <td>235</td>\n",
       "      <td>235</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>JP</th>\n",
       "      <td>251</td>\n",
       "      <td>251</td>\n",
       "      <td>251</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>UK</th>\n",
       "      <td>250</td>\n",
       "      <td>250</td>\n",
       "      <td>250</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>264</td>\n",
       "      <td>264</td>\n",
       "      <td>264</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      A    B    C\n",
       "GR  235  235  235\n",
       "JP  251  251  251\n",
       "UK  250  250  250\n",
       "US  264  264  264"
      ]
     },
     "execution_count": 148,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.count()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>GR</th>\n",
       "      <td>284</td>\n",
       "      <td>284</td>\n",
       "      <td>284</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>JP</th>\n",
       "      <td>242</td>\n",
       "      <td>242</td>\n",
       "      <td>242</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>UK</th>\n",
       "      <td>234</td>\n",
       "      <td>234</td>\n",
       "      <td>234</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>240</td>\n",
       "      <td>240</td>\n",
       "      <td>240</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      A    B    C\n",
       "GR  284  284  284\n",
       "JP  242  242  242\n",
       "UK  234  234  234\n",
       "US  240  240  240"
      ]
     },
     "execution_count": 149,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped_trans.count()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GR    284\n",
       "JP    242\n",
       "UK    234\n",
       "US    240\n",
       "dtype: int64"
      ]
     },
     "execution_count": 150,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped_trans.size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>None</th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>US</td>\n",
       "      <td>0.828127</td>\n",
       "      <td>-0.110294</td>\n",
       "      <td>0.035183</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>JP</td>\n",
       "      <td>1.027962</td>\n",
       "      <td>-0.060075</td>\n",
       "      <td>-0.458134</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>US</td>\n",
       "      <td>-0.004339</td>\n",
       "      <td>0.005199</td>\n",
       "      <td>-0.842601</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>JP</td>\n",
       "      <td>-0.081081</td>\n",
       "      <td>-0.607193</td>\n",
       "      <td>-1.168593</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>UK</td>\n",
       "      <td>1.058312</td>\n",
       "      <td>-1.303463</td>\n",
       "      <td>-1.633475</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>GR</td>\n",
       "      <td>0.247164</td>\n",
       "      <td>0.706189</td>\n",
       "      <td>-0.499013</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>JP</td>\n",
       "      <td>0.835416</td>\n",
       "      <td>-1.240551</td>\n",
       "      <td>-0.705808</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>UK</td>\n",
       "      <td>0.922992</td>\n",
       "      <td>-1.361350</td>\n",
       "      <td>-2.774647</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>UK</td>\n",
       "      <td>0.442373</td>\n",
       "      <td>-1.421477</td>\n",
       "      <td>-1.532760</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>UK</td>\n",
       "      <td>-1.218626</td>\n",
       "      <td>-1.069070</td>\n",
       "      <td>-0.111141</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>JP</td>\n",
       "      <td>-0.539695</td>\n",
       "      <td>1.605281</td>\n",
       "      <td>1.009351</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>JP</td>\n",
       "      <td>0.652668</td>\n",
       "      <td>-0.779819</td>\n",
       "      <td>-0.300812</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>US</td>\n",
       "      <td>1.248701</td>\n",
       "      <td>0.334853</td>\n",
       "      <td>-0.608131</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>JP</td>\n",
       "      <td>1.288052</td>\n",
       "      <td>-0.745468</td>\n",
       "      <td>-0.084383</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>UK</td>\n",
       "      <td>0.898373</td>\n",
       "      <td>0.737381</td>\n",
       "      <td>-0.603305</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>US</td>\n",
       "      <td>0.021726</td>\n",
       "      <td>-1.075966</td>\n",
       "      <td>2.478926</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>UK</td>\n",
       "      <td>0.037722</td>\n",
       "      <td>1.730717</td>\n",
       "      <td>0.509116</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>UK</td>\n",
       "      <td>1.266556</td>\n",
       "      <td>1.597435</td>\n",
       "      <td>-0.947602</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>GR</td>\n",
       "      <td>-0.487010</td>\n",
       "      <td>1.019425</td>\n",
       "      <td>-1.595519</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>UK</td>\n",
       "      <td>-0.371871</td>\n",
       "      <td>-0.076881</td>\n",
       "      <td>-0.406905</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>JP</td>\n",
       "      <td>0.885168</td>\n",
       "      <td>1.484506</td>\n",
       "      <td>0.504318</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>UK</td>\n",
       "      <td>1.565723</td>\n",
       "      <td>-0.679566</td>\n",
       "      <td>-0.383199</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>US</td>\n",
       "      <td>-0.548021</td>\n",
       "      <td>-3.406284</td>\n",
       "      <td>-1.112583</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>JP</td>\n",
       "      <td>-0.308757</td>\n",
       "      <td>0.370648</td>\n",
       "      <td>-1.516904</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>US</td>\n",
       "      <td>-1.056791</td>\n",
       "      <td>0.516554</td>\n",
       "      <td>-0.167072</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>US</td>\n",
       "      <td>0.550842</td>\n",
       "      <td>0.387992</td>\n",
       "      <td>0.771594</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>GR</td>\n",
       "      <td>0.321925</td>\n",
       "      <td>1.569165</td>\n",
       "      <td>-1.024612</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>JP</td>\n",
       "      <td>0.736870</td>\n",
       "      <td>-1.172039</td>\n",
       "      <td>-0.451927</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>US</td>\n",
       "      <td>1.212018</td>\n",
       "      <td>-0.866973</td>\n",
       "      <td>-1.208125</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>US</td>\n",
       "      <td>-0.948226</td>\n",
       "      <td>-1.032819</td>\n",
       "      <td>-0.093462</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>970</th>\n",
       "      <td>US</td>\n",
       "      <td>1.881078</td>\n",
       "      <td>-0.781257</td>\n",
       "      <td>-2.361841</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>971</th>\n",
       "      <td>US</td>\n",
       "      <td>0.542197</td>\n",
       "      <td>-0.906827</td>\n",
       "      <td>0.047851</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>972</th>\n",
       "      <td>UK</td>\n",
       "      <td>-0.040906</td>\n",
       "      <td>0.342534</td>\n",
       "      <td>0.141210</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>973</th>\n",
       "      <td>GR</td>\n",
       "      <td>0.064292</td>\n",
       "      <td>0.818153</td>\n",
       "      <td>0.253456</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>974</th>\n",
       "      <td>GR</td>\n",
       "      <td>-0.051890</td>\n",
       "      <td>2.050634</td>\n",
       "      <td>0.600088</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>975</th>\n",
       "      <td>JP</td>\n",
       "      <td>-0.206901</td>\n",
       "      <td>-0.295143</td>\n",
       "      <td>-0.699548</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>976</th>\n",
       "      <td>US</td>\n",
       "      <td>-0.095685</td>\n",
       "      <td>1.010718</td>\n",
       "      <td>-0.351998</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>977</th>\n",
       "      <td>US</td>\n",
       "      <td>-0.963164</td>\n",
       "      <td>0.514926</td>\n",
       "      <td>1.307137</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>978</th>\n",
       "      <td>JP</td>\n",
       "      <td>-0.331447</td>\n",
       "      <td>0.024692</td>\n",
       "      <td>0.987817</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>979</th>\n",
       "      <td>GR</td>\n",
       "      <td>0.363296</td>\n",
       "      <td>0.055889</td>\n",
       "      <td>0.222069</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>980</th>\n",
       "      <td>JP</td>\n",
       "      <td>-2.330593</td>\n",
       "      <td>-0.623006</td>\n",
       "      <td>0.740125</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>981</th>\n",
       "      <td>UK</td>\n",
       "      <td>-1.709674</td>\n",
       "      <td>0.537182</td>\n",
       "      <td>-0.728226</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>982</th>\n",
       "      <td>UK</td>\n",
       "      <td>-1.999581</td>\n",
       "      <td>1.024241</td>\n",
       "      <td>0.389662</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>983</th>\n",
       "      <td>JP</td>\n",
       "      <td>-0.101936</td>\n",
       "      <td>-0.487496</td>\n",
       "      <td>1.349537</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>984</th>\n",
       "      <td>UK</td>\n",
       "      <td>-0.960504</td>\n",
       "      <td>-1.075182</td>\n",
       "      <td>0.400736</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>985</th>\n",
       "      <td>GR</td>\n",
       "      <td>-1.738227</td>\n",
       "      <td>-0.003839</td>\n",
       "      <td>2.204468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>986</th>\n",
       "      <td>JP</td>\n",
       "      <td>0.253496</td>\n",
       "      <td>-1.034156</td>\n",
       "      <td>-0.519874</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>987</th>\n",
       "      <td>JP</td>\n",
       "      <td>-0.397488</td>\n",
       "      <td>-0.439153</td>\n",
       "      <td>-0.284092</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>988</th>\n",
       "      <td>JP</td>\n",
       "      <td>1.839780</td>\n",
       "      <td>0.460715</td>\n",
       "      <td>-0.537275</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>989</th>\n",
       "      <td>US</td>\n",
       "      <td>-1.391903</td>\n",
       "      <td>-0.832412</td>\n",
       "      <td>-0.697537</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>990</th>\n",
       "      <td>JP</td>\n",
       "      <td>0.111827</td>\n",
       "      <td>0.871810</td>\n",
       "      <td>-2.185444</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>991</th>\n",
       "      <td>US</td>\n",
       "      <td>-0.480684</td>\n",
       "      <td>0.179963</td>\n",
       "      <td>0.845224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>992</th>\n",
       "      <td>US</td>\n",
       "      <td>0.825410</td>\n",
       "      <td>-0.723115</td>\n",
       "      <td>0.932190</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>993</th>\n",
       "      <td>UK</td>\n",
       "      <td>0.979648</td>\n",
       "      <td>0.758937</td>\n",
       "      <td>1.579080</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>994</th>\n",
       "      <td>GR</td>\n",
       "      <td>1.652681</td>\n",
       "      <td>-1.966458</td>\n",
       "      <td>-0.437036</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>995</th>\n",
       "      <td>US</td>\n",
       "      <td>-1.078268</td>\n",
       "      <td>-0.203733</td>\n",
       "      <td>0.288298</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>996</th>\n",
       "      <td>US</td>\n",
       "      <td>0.217226</td>\n",
       "      <td>-0.209543</td>\n",
       "      <td>-0.128268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>997</th>\n",
       "      <td>US</td>\n",
       "      <td>1.177620</td>\n",
       "      <td>0.471514</td>\n",
       "      <td>-1.479206</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>998</th>\n",
       "      <td>JP</td>\n",
       "      <td>-0.416937</td>\n",
       "      <td>0.720835</td>\n",
       "      <td>1.069728</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>999</th>\n",
       "      <td>US</td>\n",
       "      <td>-2.292125</td>\n",
       "      <td>-0.042686</td>\n",
       "      <td>0.270454</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1000 rows × 4 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "    NaN         A         B         C\n",
       "0    US  0.828127 -0.110294  0.035183\n",
       "1    JP  1.027962 -0.060075 -0.458134\n",
       "2    US -0.004339  0.005199 -0.842601\n",
       "3    JP -0.081081 -0.607193 -1.168593\n",
       "4    UK  1.058312 -1.303463 -1.633475\n",
       "5    GR  0.247164  0.706189 -0.499013\n",
       "6    JP  0.835416 -1.240551 -0.705808\n",
       "7    UK  0.922992 -1.361350 -2.774647\n",
       "8    UK  0.442373 -1.421477 -1.532760\n",
       "9    UK -1.218626 -1.069070 -0.111141\n",
       "10   JP -0.539695  1.605281  1.009351\n",
       "11   JP  0.652668 -0.779819 -0.300812\n",
       "12   US  1.248701  0.334853 -0.608131\n",
       "13   JP  1.288052 -0.745468 -0.084383\n",
       "14   UK  0.898373  0.737381 -0.603305\n",
       "15   US  0.021726 -1.075966  2.478926\n",
       "16   UK  0.037722  1.730717  0.509116\n",
       "17   UK  1.266556  1.597435 -0.947602\n",
       "18   GR -0.487010  1.019425 -1.595519\n",
       "19   UK -0.371871 -0.076881 -0.406905\n",
       "20   JP  0.885168  1.484506  0.504318\n",
       "21   UK  1.565723 -0.679566 -0.383199\n",
       "22   US -0.548021 -3.406284 -1.112583\n",
       "23   JP -0.308757  0.370648 -1.516904\n",
       "24   US -1.056791  0.516554 -0.167072\n",
       "25   US  0.550842  0.387992  0.771594\n",
       "26   GR  0.321925  1.569165 -1.024612\n",
       "27   JP  0.736870 -1.172039 -0.451927\n",
       "28   US  1.212018 -0.866973 -1.208125\n",
       "29   US -0.948226 -1.032819 -0.093462\n",
       "..   ..       ...       ...       ...\n",
       "970  US  1.881078 -0.781257 -2.361841\n",
       "971  US  0.542197 -0.906827  0.047851\n",
       "972  UK -0.040906  0.342534  0.141210\n",
       "973  GR  0.064292  0.818153  0.253456\n",
       "974  GR -0.051890  2.050634  0.600088\n",
       "975  JP -0.206901 -0.295143 -0.699548\n",
       "976  US -0.095685  1.010718 -0.351998\n",
       "977  US -0.963164  0.514926  1.307137\n",
       "978  JP -0.331447  0.024692  0.987817\n",
       "979  GR  0.363296  0.055889  0.222069\n",
       "980  JP -2.330593 -0.623006  0.740125\n",
       "981  UK -1.709674  0.537182 -0.728226\n",
       "982  UK -1.999581  1.024241  0.389662\n",
       "983  JP -0.101936 -0.487496  1.349537\n",
       "984  UK -0.960504 -1.075182  0.400736\n",
       "985  GR -1.738227 -0.003839  2.204468\n",
       "986  JP  0.253496 -1.034156 -0.519874\n",
       "987  JP -0.397488 -0.439153 -0.284092\n",
       "988  JP  1.839780  0.460715 -0.537275\n",
       "989  US -1.391903 -0.832412 -0.697537\n",
       "990  JP  0.111827  0.871810 -2.185444\n",
       "991  US -0.480684  0.179963  0.845224\n",
       "992  US  0.825410 -0.723115  0.932190\n",
       "993  UK  0.979648  0.758937  1.579080\n",
       "994  GR  1.652681 -1.966458 -0.437036\n",
       "995  US -1.078268 -0.203733  0.288298\n",
       "996  US  0.217226 -0.209543 -0.128268\n",
       "997  US  1.177620  0.471514 -1.479206\n",
       "998  JP -0.416937  0.720835  1.069728\n",
       "999  US -2.292125 -0.042686  0.270454\n",
       "\n",
       "[1000 rows x 4 columns]"
      ]
     },
     "execution_count": 151,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped.ffill()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.5.1 New syntax to window and resample operations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>1</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>1</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>5</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>5</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>5</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>5</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>5</td>\n",
       "      <td>14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>5</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>5</td>\n",
       "      <td>16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>5</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>5</td>\n",
       "      <td>18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>5</td>\n",
       "      <td>19</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    A   B\n",
       "0   1   0\n",
       "1   1   1\n",
       "2   1   2\n",
       "3   1   3\n",
       "4   1   4\n",
       "5   1   5\n",
       "6   1   6\n",
       "7   1   7\n",
       "8   1   8\n",
       "9   1   9\n",
       "10  5  10\n",
       "11  5  11\n",
       "12  5  12\n",
       "13  5  13\n",
       "14  5  14\n",
       "15  5  15\n",
       "16  5  16\n",
       "17  5  17\n",
       "18  5  18\n",
       "19  5  19"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_re = pd.DataFrame({'A': [1]*10 + [5]*10,'B': np.arange(20)})\n",
    "df_re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "A    \n",
       "1  0      NaN\n",
       "   1      NaN\n",
       "   2      NaN\n",
       "   3      1.5\n",
       "   4      2.5\n",
       "   5      3.5\n",
       "   6      4.5\n",
       "   7      5.5\n",
       "   8      6.5\n",
       "   9      7.5\n",
       "5  10     NaN\n",
       "   11     NaN\n",
       "   12     NaN\n",
       "   13    11.5\n",
       "   14    12.5\n",
       "   15    13.5\n",
       "   16    14.5\n",
       "   17    15.5\n",
       "   18    16.5\n",
       "   19    17.5\n",
       "Name: B, dtype: float64"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_re.groupby('A').rolling(4).B.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "MultiIndex(levels=[[1, 5], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]],\n",
       "           labels=[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]],\n",
       "           names=['A', None])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result=df_re.groupby('A').rolling(2).B.sum()\n",
    "\n",
    "result.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"10\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4.0</td>\n",
       "      <td>6.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5.0</td>\n",
       "      <td>10.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6.0</td>\n",
       "      <td>15.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>7.0</td>\n",
       "      <td>21.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>8.0</td>\n",
       "      <td>28.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>9.0</td>\n",
       "      <td>36.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>10.0</td>\n",
       "      <td>45.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"10\" valign=\"top\">5</th>\n",
       "      <th>10</th>\n",
       "      <td>5.0</td>\n",
       "      <td>10.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>10.0</td>\n",
       "      <td>21.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>15.0</td>\n",
       "      <td>33.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>20.0</td>\n",
       "      <td>46.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>25.0</td>\n",
       "      <td>60.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>30.0</td>\n",
       "      <td>75.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>35.0</td>\n",
       "      <td>91.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>40.0</td>\n",
       "      <td>108.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>45.0</td>\n",
       "      <td>126.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>50.0</td>\n",
       "      <td>145.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         A      B\n",
       "A                \n",
       "1 0    1.0    0.0\n",
       "  1    2.0    1.0\n",
       "  2    3.0    3.0\n",
       "  3    4.0    6.0\n",
       "  4    5.0   10.0\n",
       "  5    6.0   15.0\n",
       "  6    7.0   21.0\n",
       "  7    8.0   28.0\n",
       "  8    9.0   36.0\n",
       "  9   10.0   45.0\n",
       "5 10   5.0   10.0\n",
       "  11  10.0   21.0\n",
       "  12  15.0   33.0\n",
       "  13  20.0   46.0\n",
       "  14  25.0   60.0\n",
       "  15  30.0   75.0\n",
       "  16  35.0   91.0\n",
       "  17  40.0  108.0\n",
       "  18  45.0  126.0\n",
       "  19  50.0  145.0"
      ]
     },
     "execution_count": 155,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_re.groupby('A').expanding().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>group</th>\n",
       "      <th>val</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2016-01-03</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-10</th>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-17</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-24</th>\n",
       "      <td>2</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            group  val\n",
       "date                  \n",
       "2016-01-03      1    5\n",
       "2016-01-10      1    6\n",
       "2016-01-17      2    7\n",
       "2016-01-24      2    8"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_re = pd.DataFrame({'date': pd.date_range(start='2016-01-01',periods=4,freq='W'),\n",
    "                      'group': [1, 1, 2, 2],\n",
    "                      'val': [5, 6, 7, 8]}).set_index('date')\n",
    "df_re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>group</th>\n",
       "      <th>val</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>group</th>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"8\" valign=\"top\">1</th>\n",
       "      <th>2016-01-03</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-04</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-05</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-06</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-07</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-08</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-09</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-10</th>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"8\" valign=\"top\">2</th>\n",
       "      <th>2016-01-17</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-18</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-19</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-20</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-21</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-22</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-23</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-24</th>\n",
       "      <td>2</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  group  val\n",
       "group date                  \n",
       "1     2016-01-03      1    5\n",
       "      2016-01-04      1    5\n",
       "      2016-01-05      1    5\n",
       "      2016-01-06      1    5\n",
       "      2016-01-07      1    5\n",
       "      2016-01-08      1    5\n",
       "      2016-01-09      1    5\n",
       "      2016-01-10      1    6\n",
       "2     2016-01-17      2    7\n",
       "      2016-01-18      2    7\n",
       "      2016-01-19      2    7\n",
       "      2016-01-20      2    7\n",
       "      2016-01-21      2    7\n",
       "      2016-01-22      2    7\n",
       "      2016-01-23      2    7\n",
       "      2016-01-24      2    8"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_re.groupby('group').resample('1D').ffill()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 16.6 Filtration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1: Int64Index([0, 1], dtype='int64'),\n",
       " 2: Int64Index([2], dtype='int64'),\n",
       " 3: Int64Index([3, 4, 5], dtype='int64')}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sf = pd.Series([1, 1, 2, 3, 3, 3])\n",
    "sf_grouped=sf.groupby(sf)\n",
    "sf_grouped.groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3    3\n",
       "4    3\n",
       "5    3\n",
       "dtype: int64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sf.groupby(sf).filter(lambda x: x.sum() > 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>a</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>a</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>6</td>\n",
       "      <td>c</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>7</td>\n",
       "      <td>c</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   A  B\n",
       "0  0  a\n",
       "1  1  a\n",
       "2  2  b\n",
       "3  3  b\n",
       "4  4  b\n",
       "5  5  b\n",
       "6  6  c\n",
       "7  7  c"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dff = pd.DataFrame({'A': np.arange(8), 'B': list('aabbbbcc')})\n",
    "dff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   A  B\n",
       "2  2  b\n",
       "3  3  b\n",
       "4  4  b\n",
       "5  5  b"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dff.groupby('B').filter(lambda x: len(x) > 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2.0</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3.0</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4.0</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5.0</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     A    B\n",
       "0  NaN  NaN\n",
       "1  NaN  NaN\n",
       "2  2.0    b\n",
       "3  3.0    b\n",
       "4  4.0    b\n",
       "5  5.0    b\n",
       "6  NaN  NaN\n",
       "7  NaN  NaN"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dff.groupby('B').filter(lambda x: len(x) > 2, dropna=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>b</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>b</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>b</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5</td>\n",
       "      <td>b</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   A  B  C\n",
       "2  2  b  2\n",
       "3  3  b  3\n",
       "4  4  b  4\n",
       "5  5  b  5"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dff['C'] = np.arange(8)\n",
    "dff.groupby('B').filter(lambda x: len(x['C']) > 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 16.8 Flexible apply"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "df = pd.DataFrame({'A':['foo', 'bar','foo', 'bar','foo', 'bar','foo', 'foo'], \n",
    "                   'C': np.arange(8),\n",
    "                   'D': np.arange(8), \n",
    "                   'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three']})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = df.groupby('A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "A         \n",
       "bar  count    3.000000\n",
       "     mean     3.000000\n",
       "     std      2.000000\n",
       "     min      1.000000\n",
       "     25%      2.000000\n",
       "     50%      3.000000\n",
       "     75%      4.000000\n",
       "     max      5.000000\n",
       "foo  count    5.000000\n",
       "     mean     3.800000\n",
       "     std      2.863564\n",
       "     min      0.000000\n",
       "     25%      2.000000\n",
       "     50%      4.000000\n",
       "     75%      6.000000\n",
       "     max      7.000000\n",
       "Name: C, dtype: float64"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped['C'].apply(lambda x: x.describe())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = df.groupby('A')['C']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>demeaned</th>\n",
       "      <th>original</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-3.8</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-2.0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-1.8</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.0</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.2</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>2.0</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2.2</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>3.2</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   demeaned  original\n",
       "0      -3.8         0\n",
       "1      -2.0         1\n",
       "2      -1.8         2\n",
       "3       0.0         3\n",
       "4       0.2         4\n",
       "5       2.0         5\n",
       "6       2.2         6\n",
       "7       3.2         7"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def f(group):\n",
    "    return pd.DataFrame({'original' : group,\n",
    "                         'demeaned' : group - group.mean()})\n",
    "grouped.apply(f)"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [conda root]",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
